{"id":18779339,"url":"https://github.com/zostay/go-addr","last_synced_at":"2025-12-17T23:30:17.142Z","repository":{"id":57562223,"uuid":"330263525","full_name":"zostay/go-addr","owner":"zostay","description":"RFC 5322 parser for mailboxes that includes obsolete format support","archived":false,"fork":false,"pushed_at":"2022-01-05T21:13:27.000Z","size":93,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-12-29T10:28:58.464Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zostay.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-01-16T21:42:20.000Z","updated_at":"2023-05-18T10:39:35.000Z","dependencies_parsed_at":"2022-09-16T13:30:40.179Z","dependency_job_id":null,"html_url":"https://github.com/zostay/go-addr","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zostay%2Fgo-addr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zostay%2Fgo-addr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zostay%2Fgo-addr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zostay%2Fgo-addr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zostay","download_url":"https://codeload.github.com/zostay/go-addr/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239690529,"owners_count":19681119,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T20:19:40.814Z","updated_at":"2025-12-17T23:30:17.096Z","avatar_url":"https://github.com/zostay.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# RFC 5322 Email Address Parser for Go\n\nThis aims at being a complete and correct RFC 5322 email address parser. It is\nnot aimed at being fast. I wish I could say the same for the built in `net/mail`\npackage, but as of this writing, the built-in library is incapable of parsing\nobsolete forms (which make up much of the Internet). This is still unlikely to\nbe capable of parsing every address or list of addresses found in the wild. The\nworld of email is just a dangerous place.\n\nThis is written in pure Go using a hand-written recursive descent parser. This\nis actually a port of a similar library I wrote for Raku.\n\n## Synopsis\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n\n    \"github.com/zostay/go-addr/pkg/addr\"\n)\n\nfunc main() {\n    addresses := \"\\\"J.R.R. Tolkein\\\" \u003cj.r.r.tolkein@example.com\u003e, \\\"C.S. Lewis\\\" \u003cjack@example.com\u003e\"\n    as, err := addr.ParseEmailAddressList(addresses)\n    if err != nil {\n        panic(err)\n    }\n\n    for _, a := range as {\n        fmt.Println(\"Name: \" + a.DisplayName())\n        fmt.Println(\"Addr: \" + a.Address())\n    }\n\n    // Output: \n    // Name: J.R.R. Tolkein\n    // Addr: j.r.r.tolkein@example.com\n    // Name: C.S. Lewis\n    // Addr: jack@example.com\n}\n```\n\n## Description\n\nThis is intended to provide a more complete email address parsing apparatus that\nI can trust and tweak to suit my needs.\n\n## Email Address Formats Parsed\n\nThis library uses terminology taken from RFC 5322.\n\n### Address\n\nAn email address is either a mailbox or a group. (See below.)\n\n### Address List\n\nAn email address list is a list of of mailboxes or groups or mixture of both\nseparated by commas. \n\nFor example:\n\n```\n\"J.R.R. Tolkein\" \u003cj.r.r.tolkein@example.com\u003e,\n\"C.S. Lewis\" \u003cjack@example.com\u003e,\nDistopian: \"George Orwell\" \u003cbb.is.watching@example.com,\n\"Aldous Huxley\" \u003csoma@example.com\u003e,\nmockingjay@exampel.com;,\n\"Alexander Dumas\" \u003cad@example.com\u003e\n```\n\nThis list contains three mailboxes and one group, which contains three more\nmailboxes.\n\n### Mailbox\n\nAn email mailbox is what most people think of as an email address. It's either\njust a plain email address or it's a display name paired with an email address\nin angle brackets or just an email address. Mailboxes may also contain comments,\nwhich is just text inside of matched pairs of parentheses.\n\n`\"Douglas Adams\" \u003cda@example.com\u003e (DON'T PANIC!)`\n\n### Mailbox List\n\nThis is a list of mailboxes without groups separated by commas.\n\n### Group\n\nThis is a single group mailbox, which is a name followed by a colon, followed by\nzero or more mailboxes separated by commas and is ended by a semi-colon.\n\n### AddrSpec\n\nIn RFC 5322, the email address with no decoration is called an addr-spec.\nincludes just the email address itself.\n\n### Obsolete Forms\n\nThis parser also works for parsing obsolete forms that go all the way back to\nRFC 822.\n\n## Parsing Functions\n\nThese are all part of the `github.com/zostay/go-addr/pkg/addr` package. All of\nthese functions may return an error if there's a problem during the parse or if\nparser can't find an address in the input.\n\nIf the input string starts with something that can be parsed as an email\naddress, but can't be completely parsed, then the part that can be parsed will\nbe returned and a `PartialParseError` will be returned as the error. This has a\n`Remainder` field that can be used to retrieve the unparsed part:\n\n```go\npackage main\n\nimport (\n\t\"errors\"\n\t\"fmt\"\n\n\t\"github.com/zostay/go-addr/pkg/addr\"\n)\n\nfunc main() {\n\tmb, err := addr.ParseEmailMailbox(\n\t\t\"\\\"CS\\\" \u003ccharles.sheffield@example.com\u003e and extra text\",\n\t)\n\n\tvar r string\n\tvar ppe addr.PartialParseError\n\tif errors.As(err, \u0026ppe) {\n\t\tr = ppe.Remainder\n\t} else if err != nil {\n\t\tpanic(err)\n\t}\n\n\tfmt.Printf(\"Parsed: %s\\n\", mb)\n\tfmt.Printf(\"Remainder: %s\\n\", r)\n    \n    // Output:\n    // Parsed: \"CS\" \u003ccharles.sheffield@example.com\u003e\n    // Remainder: and extra text\n}\n```\n\n### addr.ParseEmailAddress\n\n`func ParseEmailAddress(a string) (addr.Address, error)`\n\nThis parses a single email address. This can parse either a mailbox address or a\ngroup list. The object returned will be either an `addr.Group` or an\n`addr.Mailbox`.\n\n### addr.ParseEmailAddressList\n\n`func ParseEmailAddressList(a string) (addr.AddressList, error)`\n\nAn `addr.AddressList` is a slice of `addr.Address`. This will parse a list of\nmailbox and/or group email addresses separated by commas.\n\n### addr.ParseEmailMailbox\n\n`func ParseEmailMailbox(a string) (*addr.Mailbox, error)`\n\nThis will parse a single mailbox address.\n\n### addr.ParseMailMailboxList\n\n`func ParseEmailMailboxList(a string) (addr.MailboxList, error)`\n\nAn `addr.MailboxList` is a slice of `*addr.Mailbox`. This will parse a list of\nmailbox email addresses separated by commas.\n\n### addr.ParseEmailGroup\n\n`func ParseEmailGroup(a string) (*addr.Group, error)`\n\nThis will parse a single group address.\n\n### addr.ParseEmailAddrSpec(a string) (*addr.AddrSpec, error)`\n\n`func ParseEmailAddrSpec(a string) (*addr.AddrSpec, error)`\n\nThis will parse a single `addr-spec`.\n\n## net/mail\n\nIf you want to convert mailbox email addresses from this library into those of\nthe `net/mail` package built-in to Go, you just need to do the following:\n\n```\npackage main\n\nimport (\n    \"fmt\"\n    \"net/mail\"\n\n    \"github.com/zostay/go-addr/pkg/addr\"\n)\n\nfunc main() {\n    addrmb, _ := addr.ParseEmailMailbox(\"\\\"David Weber\\\" \u003chonorh@example.com\u003e\")\n    mailmb := mail.Address{addrmb.DisplayName(), addrmb.Address()}\n    fmt.Println(mailmb)\n    // Output: {David Weber honorh@example.com}\n}\n```\n\nThat's simple enough and there are enough other useful mail handling libraries\nout there, I didn't bother providing a conversion helper. You can write your own\nin a couple lines of Go.\n\n## Copyright and License\n\nCopyright 2020 Andrew Sterling Hanenkamp\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzostay%2Fgo-addr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzostay%2Fgo-addr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzostay%2Fgo-addr/lists"}