Skip to content

Rework letters into submodules, add pluggable funcs and parser options #124

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

Closed
wants to merge 20 commits into from

Conversation

rorycl
Copy link

@rorycl rorycl commented Feb 6, 2025

This is a rewrite of letters to use submodules with local testing and provide parser options together with pluggable funcs.

The main benefits of the rewrite is to allow:

  • the use of methods on Parser to share state while processing
  • support for pluggable funcs, most notably to allow custom file filtering and/or parsing to avoid reading whole files into memory.
  • the provision of options to customise the operation of the parser.
    See opts_test.go and the optpkg_test package tests for usage examples.
  • a more modular approach in general which will hopefully encourage incremental improvements to be made in future.
  • a reduction in code and addition of comments.

The use of string types for email Content* information is, I think, still a bit of a mess and could be further rationalised since very little of this information is exposed to the user. Where it is exposed it would be better to simply use strings and simple string maps for easier usage.

I'm not sure we've been able to have a fruitful discussion about the above topics. I hope nevertheless there are some useful ideas here to help make the most of the very clear benefits of letters. It seems more fun and reasonable to collaborate, but in the absence of a chance for a discussion I'll probably make a hard fork.

To try this PR out you may need to use go workspaces since the submodules ("email", "decoders" and "parser") don't exist in the published letters namespace.

rorycl added 10 commits February 6, 2025 11:44
This patch expands on the comments for the Email type and subtypes. Some
type names have been changed to allow for use as an external package.

The separate inline and attached file types have been incorporated into
a single "File" type. The new file type exposes a number of new fields
including the underlying io.Reader.
This patch splits the parser into parts:
* header : for processing header information
* body   : for processing body information
* files  : for processing file information

The use of methods on the main Parser struct shares state conveniently
while building up a new letters.email.Email from a net/mail.Message.

The Parser constructor allows for user-supplied functions to be used for
aspects such as date, address and file parsing. Notably, the provision
of a "fileFunc" allows users to bypass first reading an inline or
attached file into bytes before further processing.
This patch sets out the following "With" options for parsing:

    WithVerbose()
    WithHeadersOnly()
    WithoutAttachments()
    WithCustomDateFunc(df func(string)
    WithCustomAddressFunc(af func(string)
    WithCustomAddressesFunc(af func(list string)
    WithCustomFileFunc(ff func(*email.File)
    WithSaveFilesToDirectory(dir string)
@rorycl rorycl requested a review from mnako as a code owner February 6, 2025 12:25
@rorycl
Copy link
Author

rorycl commented Feb 8, 2025

Hi @mnako

With this addditional patch set I've now abstracted the Content-* capabilities into a new struct and methods.

Email headers and files now report their content information in structs along the following lines:

ContentInfo: &email.ContentInfo{
    Type: "text/plain",
    TypeParams: map[string]string{
        "charset": "ascii",
    },
    Disposition:       "",
    DispositionParams: map[string]string(nil),
    TransferEncoding:  "quoted-printable",
    ID:                "",
    Charset:           "ascii",
},

I have regenerated all the tests using utils/testRegen.go.

To try out this branch you may need a go.work file along the following lines:

replace github.com/mnako/letters/parser@latest => ./parser
replace github.com/mnako/letters/email@latest => ./email
replace github.com/mnako/letters/decoders@latest => ./decoders

use (
    .
    ./email
    ./parser
    ./decoders
)

@rorycl
Copy link
Author

rorycl commented Feb 8, 2025

I've made my fork. I hope you find a few ideas that are useful in my code reorganisation. Thanks for the great work on decoding in particular!

@rorycl rorycl closed this Feb 8, 2025
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

Successfully merging this pull request may close these issues.

1 participant