Skip to content
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

Parsing Envelope #15

Closed
FelixPodint opened this issue Mar 18, 2022 · 10 comments
Closed

Parsing Envelope #15

FelixPodint opened this issue Mar 18, 2022 · 10 comments

Comments

@FelixPodint
Copy link
Contributor

Hi,
Is there a way to parse raw bytes &[8u], Vec<u8> to Envelope struct?

Thanks.
With respect,
Felix P.

@duesee
Copy link
Owner

duesee commented Mar 18, 2022

The envelope function should be what you need. However, it is pub(crate), i.e., not exposed via a public API. Can you tell me a bit about your use case? Trying to understand if it would make sense to expose something like use imap_codec::nom::envelope.

@duesee
Copy link
Owner

duesee commented Mar 18, 2022

Actually, I like the idea of having an "ecosystem" of composable nom functions. Thus, I would be happy to expose (all) parsers via imap_codec::nom::*. Do you like to make that PR? :-) I will be at home in some hours and can review the PR (or commit something myself).

@FelixPodint
Copy link
Contributor Author

FelixPodint commented Mar 18, 2022

I'm using SQLite to store mail messages for my IMAP server. Currently I store envelope information as data blob inside this database. I don't know, maybe I should store all envelope fields as separate columns. That way I would just construct new Envelope struct from separate SLQ columns.
I think it would be nice to have methods to go from bytes to structs, the same way as we can already go from structs to bytes with .encode(writer).

Please commit yourself, if its not a problem for you, I'll be out for a weekend.
Thanks.

@FelixPodint
Copy link
Contributor Author

Ok, before I do anything, I want to ask.
Do you want new pub mod nom with re-exports of functions from mod parse or do you want to replace mod parse with mod nom?
Creating a separate mod nom would allow us to aggregate all [from bytes to struct] functions into one place, while keeping mod parse structure intact. Not sure how to nicely put [from struct to bytes] function (aka. .encode(writer)) to mod nom.

@FelixPodint
Copy link
Contributor Author

I think Decode trait would be the best option. (Easiest to understand for new users)

@duesee
Copy link
Owner

duesee commented Mar 22, 2022

Hey @FelixPodint,

Sorry, I didn't had too much time to look into it. Thanks for taking care!

Do you want new pub mod nom with re-exports of functions from mod parse or do you want to replace mod parse with mod nom?

I also think mod parse should stay for now.

Creating a separate mod nom would allow us to aggregate all [from bytes to struct] functions into one place, while keeping mod parse structure intact.

Agree. I also prefer this solution. But maybe with a minor change: as far as I know, crates that use types from a dependency in their public API may reexport the dependency under the same name. Thus, I changed my mind, and think that we should reexport all parsers via imap_codec::internal:: (or something like that) and not via imap_codec::nom::. This way, we would not block a reexport of the nom dependency.

Not sure how to nicely put [from struct to bytes] function (aka. .encode(writer)) to mod nom.

Can you elaborate? Do we have to change that?

@FelixPodint
Copy link
Contributor Author

FelixPodint commented Mar 22, 2022

Agree. I also prefer this solution. But maybe with a minor change: as far as I know, crates that use types from a dependency in their public API may reexport the dependency under the same name. Thus, I changed my mind, and think that we should reexport all parsers via imap_codec::internal:: (or something like that) and not via imap_codec::nom::. This way, we would not block a reexport of the nom dependency.

Maybe pub use ::nom as nom_nom could work for re-exporting nom crate, but I agree using different name than nom is better idea.

Not sure how to nicely put [from struct to bytes] function (aka. .encode(writer)) to mod nom.

Can you elaborate? Do we have to change that?

OK lets stop and think for a moment.

  • What I want to have is a unified way to got from struct, like Envelope, to raw bytes and vice versa.

Currently we have parse module, which has functions to convert raw bytes to structs, and we have an Encode trait, which allows conversions from structs to raw bytes. So all of the most difficult parts are already done.
Maybe it's possible to have Decode trait, which mirrors Encode?

Something like this:

//=============================================
pub trait Decode
where
    Self: Sized,
{
    fn decode(input: &[u8]) -> IResult<&[u8], Self>;
}

impl Decode for Envelope {
    fn decode(input: &[u8]) -> IResult<&[u8], Self> {
        crate::parse::envelope::envelope(input)
    }
}
//=============================================
// Could be used this way by crate users.
let rez: Envelope = match imap_codec::codec::Decode::decode(&envelope_writer) {
    Ok((remaining, envelope)) => envelope,
    Err(_) => {
        panic!();
    }
};
//=============================================

@duesee
Copy link
Owner

duesee commented Mar 22, 2022

Is the proposal of a Decode trait directly relevant to the change to expose the parsers?

From my view we can first expose the parsers via an internal module, such that one can already use ...

use imap_codec::internal::envelope::envelope;

Second step, maybe in a separate issue?, would be to discuss how to unify the Encode and Decode API. I see your point and it seems desirable to have Encode and Decode. But I have some more thoughts on that we should discuss separately. What do you think?

@FelixPodint
Copy link
Contributor Author

Agree, got a little to exited.
I will make a PR for re-exports.

@duesee
Copy link
Owner

duesee commented Mar 23, 2022

Hehe, no worries :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants