Does a heap-free `Cow<'a, [u8]>` exist?

I'm playing around with how far I can take a zero-copy Json deserialization.

Imagine I have some JSON that has a field whose data (alpha ASCII bytes) are valid.
In that case I can simply take the data as a &[u8].

But I also want to normalize the field to uppercase with no surrounding ASCII whitespace and potentially remove any '-' chars from the middle of the bytes.

Best case scenario is to mutate the bytes in place, as normalizing involves leaving the slice len as is
or shrinking it. But I don't see how to deserialize into a &mut [u8] using serde::Deserialize.
I'm presuming it's not possible to acquire a &mut [u8] from serde::Deserialize so let's concentrate on allocation instead.

I can store the field as a Cow<'a, [u8]> but that will allocate on the heap.
Is there a way I can have a Cow like concept but allocate a fixed size array instead?
This is the most desirable given that I know the normalized form of the field will always be [u8; 5].

I don't know of any concept like a FixedCow<'a, T, const N: usize> but ofc I can roll my own if needed.


struct Thing<'a> {
    field: Field<'a>;

struct Field<'a>(FixedCow<'a, [u8], 5>);

impl<'de: 'a, 'a> serde::Deserialize<'de> for Field<'a> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        D: serde::Deserializer<'de>,
        let bytes: &[u8] = Deserialize::deserialize(deserializer)?;

        // validate and sanitize bytes 
        // I would like to mutate the bytes in place here
        // but I don't see a way of deserializing to a `&mut [u8]`
        // The next best thing would be to store it as a sort of `FixedCow<'a, const .: usize>`


If it's only 5 bytes, why not just use the [u8; 5] type?

Hah yes in the 5 bytes case a [u8; 5] is indeed smaller than a &[u8] :laughing:

Allow me to move the goalposts a bit.
What if the field was 36 bytes?

A type that either contains a pointer or a 36 byte array is at least 36 bytes. (assuming you don't allocate)

1 Like

Damn, true, a FixedCow makes no sense then :thinking:

Well I think that's my answer then :wink:

1 Like

Thanks :wink: