{"id":32163119,"url":"https://github.com/rpeszek/typed-encoding","last_synced_at":"2025-10-21T14:08:02.991Z","repository":{"id":56881222,"uuid":"256081540","full_name":"rpeszek/typed-encoding","owner":"rpeszek","description":"Type safe string restrictions and transformations","archived":false,"fork":false,"pushed_at":"2023-10-16T16:35:12.000Z","size":465,"stargazers_count":6,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-14T21:44:04.990Z","etag":null,"topics":["encoder-decoder","haskell-library","string-encodings","string-transformations","strings","type-safe"],"latest_commit_sha":null,"homepage":"","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rpeszek.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","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":"2020-04-16T01:47:23.000Z","updated_at":"2023-10-16T16:35:16.000Z","dependencies_parsed_at":"2022-08-20T22:31:20.257Z","dependency_job_id":null,"html_url":"https://github.com/rpeszek/typed-encoding","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/rpeszek/typed-encoding","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rpeszek%2Ftyped-encoding","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rpeszek%2Ftyped-encoding/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rpeszek%2Ftyped-encoding/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rpeszek%2Ftyped-encoding/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rpeszek","download_url":"https://codeload.github.com/rpeszek/typed-encoding/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rpeszek%2Ftyped-encoding/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280272370,"owners_count":26302268,"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","status":"online","status_checked_at":"2025-10-21T02:00:06.614Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["encoder-decoder","haskell-library","string-encodings","string-transformations","strings","type-safe"],"created_at":"2025-10-21T14:08:01.383Z","updated_at":"2025-10-21T14:08:02.983Z","avatar_url":"https://github.com/rpeszek.png","language":"Haskell","readme":"# typed-encoding\nType level annotations, string transformations, and other goodies that make programming strings safer.\n\n## Motivation\nI have recently spent a lot of time troubleshooting various `Base64`, `quoted-printable`, and `UTF-8` encoding issues.  \nI decided to write a library that will help avoiding issues like these.\n\nThis library allows to specify and work with types like\n\n```Haskell\n-- some data encoded in base 64\nmydata :: Enc '[\"enc-B64\"] c ByteString\n\n-- some text (utf8) data encoded in base 64 \nmyData :: Enc '[\"enc-B64\", \"r-UTF8\"] c ByteString\n```\n\nIt allows to define precise string content annotations like:\n\n```Haskell\nipaddr :: Enc '[\"r-IpV4\"] c Text\n```\n\nand provides ways for \n\n- encoding\n- decoding\n- recreation (encoding validation)\n- type conversions\n- converting types to encoded strings\n- typesafe conversion of encoded strings to types\n\nPartial and dangerous things like `decodeUtf8` are no longer dangerous, \n`ByteString` `Text` conversions become fully reversible.  Life is good!\n\n... but this approach seems to be a bit more...\n\n```Haskell\n-- upper cased text encoded as base64\nexample :: Enc '[\"enc-B64\", \"do-UPPER\"] () T.Text\nexample = encodeAll . toEncoding () $ \"some text goes here\"\n```\n\nIt becomes a type directed, declarative approach to string transformations.\n\nTransformations can be\n\n- used with parameters\n- applied or undone partially (if encoding is reversible)\n\nOne of more interesting uses of this library are encoding restrictions included in this library.   \nExample are (arbitrary) bounded alpha-numeric (`\"r-ban\"`) restrictions.\n\n```Haskell\n-- allow only properly formatted phone numbers\n\ntype PhoneSymbol = \"r-ban:999-999-9999\"\nphone :: Enc '[PhoneSymbol] () T.Text\nphone = ... \n```\n\nThe author often uses _typed-encoding_ with _Servant_ (`HttpApiData` instances are not included), e.g.:\n\n```Haskell\ntype LookupByPhone = \n  \"customer\"\n  :\u003e \"byphone\"\n  :\u003e Capture \"phone\" (Enc '[PhoneSymbol] () T.Text)\n  :\u003e Get '[JSON] ([Customer])\n```\n\nor to get type safety over text document using Unix vs Windows line breaks!\n\n\n## Goals and limitations\n\nThe main goal is to provide improved type safety for programs that use string encodings and \ntransformations.  _Not to provide encoding implementation type safety_. \n_Encoding and string manipulation libraries are typically well established and tested, type safety is really needed at the usage site, not at the implementation site_.\n\nThis library approach is to fight issues with (value level) strings using (type level) strings. Using `Symbol`-s effectively forces us to play the orphan instances game.   \nOne of the long term goals is for this library to provide combinator alternatives to typeclass polymorphism so that the orphan instances are more of a convenience and not the necessity.  \n\n\n## Examples \n\nHere are some code examples:\n\n- [Overview](src/Examples/TypedEncoding/Overview.hs)\n- [Conversions between encodings](src/Examples/TypedEncoding/Conversions.hs)\n- [DIY encoding, error handling](src/Examples/TypedEncoding/Instances/DiySignEncoding.hs)\n- [To and from string conversions](src/Examples/TypedEncoding/ToEncString.hs)\n- [Unsafe - working inside encodings](src/Examples/TypedEncoding/Unsafe.hs)\n \n\n## Hackage\n\nhttps://hackage.haskell.org/package/typed-encoding\n\n## Other encoding packages\n\nMy approach will be to write specific encodings (e.g. _HTTP_) or wrap encodings from other packages using separate \"bridge\" projects.\n\nCurrently /typed-encoding/ depends on\n\n- /base64-bytestring/ because it was my driving example, this is likely to move out to a separate bridge project at some point. \n\nBridge work:\n\n- [typed-encoding-encoding](https://github.com/rpeszek/typed-encoding-encoding) bridges [encoding](https://github.com/dmwit/encoding) package \n\n\n## Tested with\n\n- stack (1.9.3) lts-14.27 (ghc-8.6.5)\n- stack (2.5.1) lts-16.27 (ghc-8.8.4)\n- needs ghc \u003e= 8.2.2, base \u003e=4.10 for GHC.TypeLits support\n\n## Known issues\n\n- running test suite: cabal has problems with doctest, use stack  \n   https://github.com/haskell/cabal/issues/6087   \n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frpeszek%2Ftyped-encoding","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frpeszek%2Ftyped-encoding","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frpeszek%2Ftyped-encoding/lists"}