Q:

How to construct const integers from literal byte expressions?

Is there a way to construct a const integer from a literal byte expression, either using a byte string or a macro which constructs the integer?
For example:
const MY_ID:   u16 = u16_code!(ID);
const MY_WORD: u32 = u32_code!(WORD);
const MY_LONG: u64 = u64_code!(LONGWORD);

Or something similar, passing in b"ID" instead of ID? *
It should fail to compile when the wrong number of characters are passed too, something I couldn't figure out how to achieve when using bit-shifting on a literal byte string.

Here's a simple example that works on a basic level, but fails to ensure correctly sized arguments.
// const MY_ID: u16 = u16_code!(b"ID");
#[cfg(target_endian = "little")]
macro_rules! u16_code {
    ($w:expr) => { ((($w[0] as u16) <<  0) | (($w[1] as u16) <<  8)) }
}
#[cfg(target_endian = "big")]
macro_rules! u16_code {
    ($w:expr) => { ((($w[1] as u16) <<  0) | (($w[0] as u16) <<  8)) }
}

* See related question: Is there a byte equivalent of the 'stringify' macro?

A:

You can build a macro for each type by indexing into the array and bitshifting the parts to the correct position. An example expression for your u16 is
((b"ID"[0] as u16) << 8) | (b"ID"[1] as u16)

You can replace the b"ID" by a macro replacement $e which comes from a $e:expr.
To achieve the length check, you can insert a useless *$e as [u8; 2], which will fail to compile if the types don't match.

