Considerations to improve this idea?

⚓ Rust    📅 2025-11-19    👤 surdeus    👁️ 11      

surdeus

The snippet has a few missing items, but the question will hopefully be clear.

Context

  1. The problem involves binary file type with two Header versions.

  2. One idea was to use struct Header<B,C>, with the concrete impls:

    • impl Header<u16, u32>
    • impl Header<u32, u64>
  3. Most methods in Header need the concrete number type for comparisons so I can not implement a generic impl<A,B> Header<A,B>.

    • For example in e_machine:
     match v {
         a@4 => {...}
     }
    

    the type of v must be defined, so I can not just indicate that a is, say, num_traits:Unsigned which I tried.

  4. However, this way I get a lot of repetition (although at least I save 1 struct since my is generic at the moment Header<S,L>).

Example snippet

// my own simple buffer reader
use crate::buf_reader::BufferReader;
#[allow(dead_code)] // or it complains
#[derive(Debug)]
pub struct ElfHeader<S, L> { 
   // --snip--
    e_machine: NameValueMeaning<S>, 
    e_version: NameValueMeaning<L>,
    e_entry: L
}
impl ElfHeader<u16, u32> {
    pub fn from_buf(buf: &mut BufferReader) -> Self {
        let e_machine = Self::e_machine(buf.read_t()).unwrap();
        let e_version = Self::version(buf.read_t());
        let e_entry = buf.read_t();
     
        Self {
            e_machine,
            e_version,
            e_entry,
        }
    }


    pub fn e_machine(val: u16) -> Result<NameValueMeaning<u16>, u16> {
        // this has 200 matches, and must be repeated for `<u32>` 
        // in place of the `<u16>`
        match val {
            a@0 => Ok(NameValueMeaning{name:"...".to_owned(), value:a , meaning:"...".to_owned()}),
            a@1 => Ok(NameValueMeaning{name:"...".to_owned(), value:a , meaning:"...".to_owned()}),
            j=> {eprint!("Not a recognised format"); Err(j)}
        }
    }
    pub fn version(val: u32) -> NameValueMeaning<u32> {
        match val {
            0 => NameValueMeaning { /* ... */ },
            j => NameValueMeaning { /*...*/ },
        }
    }
}

impl ElfHeader<u32, u64> {
     // similar, just replacing u16->u32
     // u32 -> u64
    pub fn e_machine(val: u32) -> Result<NameValueMeaning<u32>, u32> {
    // same code inside !
   }
}

1 post - 1 participant

Read full topic

🏷️ Rust_feed