nom icon indicating copy to clipboard operation
nom copied to clipboard

`Input` and `Cow` (Copy-on-write)

Open chifflier opened this issue 1 year ago • 0 comments

Hi,

I'd like to parse data with generic input (so my input has bounds I: Input<Item=u8>), and store it in a Cow object. I tried many implementations but could not get it to work for all cases.

1/

I tried adding a bound for Input on the struct, however this makes using the Cow impossible:

#[derive(PartialEq, Eq)]
pub struct OctetString<'a, I = &'a [u8]>
where
    I: Input<Item = u8>,
{
    data: Cow<'a, I>,
}

This will not work, since Cow<'a, I> will be inferred as Cow<'a, &'a [u8]> (notice the extra &). If I change this to use [u8] as I, this makes Cow work, but nom complains that [u8] does not satisfy Input.

2/

So, I tried changing I to make it easier to use Cow, and change the bound for Input:

Examples implementation which works for slices:

#[derive(PartialEq, Eq)]
pub struct OctetString<'a, I = [u8]>
where
    &'a I: Input<Item = u8>,
    I: ?Sized + ToOwned,
{
    data: Cow<'a, I>,
}

With the code above, I can parse things using for ex &[u8] to build OctetString<[u8]>. However, I can't build custom input containing a span (similar to nom-locate) because this requires &CustomInput: Input<Item=u8>. I tried implementing Input for &CustomInput but can't, because take and take_fromreturn aSelf`, and I can't return a reference on a stack object.

Q/ Is there a way to have a copy-on-write type as Input? Does someone have a better solution for this?

chifflier avatar Feb 17 '25 10:02 chifflier