vendredi 19 août 2022

Advice on small public API design. Builder pattern?

I have the following use case, and I don't have enough experience to know how this is usually handled:

I am reading a file which contains some messages; these messages are divided into chunks. A Chunk is:

pub struct Chunk {
    device_id: u32,
    channel_id: u8,
    chunk_id: u16,
    payload: Vec<u8>,
}

The payload is a slice of the actual message, the chunk_id sets the position of the payload within the message. All chunks with the same device_id and channel_id form a single message.

Then a Message is:

pub struct Message {
    device_id: u32,
    channel_id: u8,
    total_payload: Vec<u8>,
}

And I have implemented TryFrom as:

impl TryFrom<Vec<Chunk>> for Message {
    type Error = String;

    fn try_from(mut chunks: Vec<Chunk>) -> Result<Self, Self::Error> {
        // Check a bunch of stuff
        // All chunks belong to the same device_id
        // All chunks belong to the same channel_id
        // etc.

        let device_id = chunks[0].device_id;
        let channel_id = chunks[0].channel_id;
        chunks.sort_unstable_by_key(|c| c.chunk_id);
        let total_payload: Vec<u8> = chunks.into_iter().flat_map(|c| c.payload).collect();

        Ok(Message {
            device_id,
            channel_id,
            total_payload,
        })
    }
}

This all works great. Now my question is: How should I handle receiving all the Chunks (from multiple device_id and channel_id)?

I was thinking about a MultipleMessagesBuilder with an add_chunk function, to which I can give it Chunks one by one. This will internally "sort" each chunk into an appropriate Vec<Chunk> depending on the device_id and channel_id. Once I have passed all the chunks, I can then call a initialize method, and it will try to make the messages from the vectors.

Does something like this make sense? How would the public API of this MultipleMessagesBuilder look like? I can't imagine a reasonable way to then obtain the messages, the errors of the ones that fail, etc.

Aucun commentaire:

Enregistrer un commentaire