-
-
Notifications
You must be signed in to change notification settings - Fork 64
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce OctetsFrom and OctetsInto. #77
Conversation
Yeah! Can you add the tests from PR#69? It should make it more obvious whether it works or not. The implementation for Record is missing. I'm trying to figure out how the traits bound would look like now. One example - converting record with a DS into another record with generic octets. Previously it would look something like this:
Now I have:
|
I have added tests to An impl for If you do want to use a function, I think just using |
One thing that I didn’t add is an impl on But maybe this just works out and I worry too much? |
@vavrusa, does this work for you now or is there still some usability issues to flesh out? |
Hi @partim sorry about the delay, I was distracted with other things. I'll make a note to try it out again this week. If I remember correctly I added Convert implementation on ParsedDname that converted into Dname. The reason for that was so that I could convert Record<N, D> from Message into something I can store in cache. It's possible without it, just that I can't do |
|
||
impl<'a, Source: AsRef<[u8]> + 'a> OctetsFrom<&'a Source> for &'a [u8] { | ||
fn octets_from(source: &'a Source) -> Result<Self, ShortBuf> { | ||
Ok(source.as_ref()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This blanket implementation is not enough. Bytes for example only supports conversion from &'static [u8]
. So converting from &Record
now requires cloning the record and converting each member using the owned value. Perhaps the blanket implementation could use OctetsBuilder which can convert any Source: AsRef<[u8]>
into Octets
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But isn’t that rather a missing impl OctetsFrom<&'_ Record<...>> for Record<...>
? Or am I misunderstanding you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes you're right, I misread this, I thought it was implemented for any AsRef<[u8]>
. This is not unique to Record though, any type composed of Octets that is convertible currently moves the original variable. I guess it's not going to be a big problem with Bytes as it can efficiently convert from a cloned vec, and cloning of bytes in order to be converted back to vec is cheap so it should be ok for now. impl<O> OctetsFrom<&'a Record<O, ...>> for Record<O, ...> where O: Clone
would be convenient, that would make the usability similar to how Dname like types can be converted using to_dname
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It think when doing from a &Record<O>
to a Record<OO>
, we should go via &O: OctetsRef
. So perhaps the trait bound should be where &O: OctetsRef, OO: OctetsFrom<&O>
(plus lifetimes, of course). There might be a blanket impl in there somewhere, but it probably won’t work because of specialization rules.
Perhaps explore this in a different PR? Just so we get some progress here?
data: Data::octets_from(source.data)? | ||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add an implementation for N: SrcName
instead? SrcName should have ToDname
, so converting an ParsedRecord<impl OctetsRef>
into Record<Dname<O>, ...>
should be possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel that this sort of thing should happen via regular From
from a ParsedDname
to its Dname
given that it actually copies things around. The intention of OctetsFrom
was really just a type conversion for the particular octet type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes that's fair, however scanning ParsedRecord and converting is common and currently very clunky.
let rr = rr.into_record::<Dnskey<_>>()?.context("empty record")?;
let rr: Record<Dname<O>, Dnskey<O>> = Record::new(rr.owner().to_dname().context("failed to convert dname")?, rr.class(), rr.ttl(), rr.into_data().octets_into().context("failed to convert data")?);
If we add impl From<ParsedDname<R>> for Dname<O>
that should make Record::from_record
work, another option is to move this into another method/trait.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there indeed lots of From
impls and other conversion helpers missing. My plan was to add them as they become necessary so as to not add too much stuff that nobody uses and that just increases the code size.
I suggest we look at conversions for records and names in a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, of course, I didn't mean to hold this up, sorry.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nono! I really appreciate the feedback. Here is as good as anywhere.
This continues from PR #69.
I think I have implemented
OctetsFrom
for all relevant types withOctetsInto
automatically available for them via a blanket impl. @vavrusa, can you have a look and let me know if this works for you or what needs changing?