{"id":13629552,"url":"https://github.com/LokiMidgard/CSV-Parser-Generator","last_synced_at":"2025-04-17T09:34:34.866Z","repository":{"id":178539788,"uuid":"657170195","full_name":"LokiMidgard/CSV-Parser-Generator","owner":"LokiMidgard","description":"A Parser for CSV with support for uncommon line separators (e.g. Unicode) and instantiation of read-only objects and working nullable handling","archived":false,"fork":false,"pushed_at":"2024-05-02T06:40:39.000Z","size":95,"stargazers_count":5,"open_issues_count":2,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-01T18:11:37.613Z","etag":null,"topics":["csv","csv-parser","source-code-generation"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LokiMidgard.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-22T13:20:46.000Z","updated_at":"2024-05-13T17:33:40.000Z","dependencies_parsed_at":"2024-01-06T02:09:49.296Z","dependency_job_id":"4cd7ed4c-91dc-48ec-9a4d-c2a9989119b1","html_url":"https://github.com/LokiMidgard/CSV-Parser-Generator","commit_stats":null,"previous_names":["lokimidgard/csv-parser-generator"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LokiMidgard%2FCSV-Parser-Generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LokiMidgard%2FCSV-Parser-Generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LokiMidgard%2FCSV-Parser-Generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LokiMidgard%2FCSV-Parser-Generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LokiMidgard","download_url":"https://codeload.github.com/LokiMidgard/CSV-Parser-Generator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223751213,"owners_count":17196589,"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":["csv","csv-parser","source-code-generation"],"created_at":"2024-08-01T22:01:13.472Z","updated_at":"2024-11-08T20:31:09.856Z","avatar_url":"https://github.com/LokiMidgard.png","language":"C#","readme":"[![NuGet](https://img.shields.io/nuget/v/CSVParserGenerator.svg?style=flat-square)](https://www.nuget.org/packages/CSVParserGenerator/)\n[![GitHub license](https://img.shields.io/github/license/LokiMidgard/CSV-Parser-Generator.svg?style=flat-square)](https://tldrlegal.com/license/mit-license#summary)\n\n\n# CSV Parser Generator\n\nA Parser for CSV with support for uncommon line separators (e.g. Unicode) and instantiation of read-only objects and working nullable handling.\n\n## Getting started\n\n\nAssuming you want to populate following Data Type\n\n```c#\nclass Person{\n    public Guid Id {get;init;}\n    public required string Name {get;init;}\n    public DateOnly Birthdate {get;init;}\n    public int Score {get;init;}\n}\n```\n\nand following data\n\n```csv\nB2DDC789-A793-4BEA-9A0B-D00FFCDD1FB5,\"John Doe\",2000-03-01,50\nBE4015A0-9B37-4A1E-A92A-405496A1FF96,\"Max Mustermann\",2001-04-01,64\n```\n\n1. Include the NuGet package\n1. Add following Method to one of your classes (the class must be partial)\n    ```c#\n    [Parser.CSVParser(nameof(Person.Id), nameof(Person.Name), nameof(Person.Birthdate), nameof(Person.Score))]\n    internal partial IEnumerable\u003cPerson\u003e ParseData(ReadOnlySpan\u003cbyte\u003e data);\n    ```\n    1. You can add an list of propertynames, this will be the colums.\n    1. You can use null to ignore some columns in the csv\n    1. You can omit the list then the colums will be assigned in order of the properties in the type. This dose not work ~~well~~ at all if the properties are defined in multiple files.\n1. Call your `ParseData` and run your program, that's it.\n\n\nYou can use `ReadOnlySpan\u003cbyte\u003e` or `ReadOnlySpan\u003cchar\u003e` as input.\n\nThe result Type must have a parameter less constructor, the properties are set\nwith `new MyType() {Property1 = …}` this allows of the `required` keyword and\n`init` property's which should led to less problems with non nullable\nproperties.\n\nContainer Types (return type of the Method) must satisfy following if they are not an Interface:\n- Have a generic argument that defines the element type\n- Have an `Add(T toadd)` Method\n\nIf they are Interfaces, they must be implemented by one of the following classes\n- `System.Collections.Immutable.ImmutableArray`\n- `System.Collections.Immutable.ImmutableHashSet`\n- `System.Collections.Immutable.ImmutableList`\n- `System.Collections.Generic.List`\n- `System.Collections.Generic.HashSet`\n- `System.Collections.Generic.HashSet`\n\nFor `ImmutableArray`, `ImmutableList` and `ImmutableHashSet` a builder is used to populate the collection\n\nThe Properties of the result type must either be string or need to implement\n`ISpanParsable\u003cT\u003e`. The Attribute has a list of Property names that will be set.\nStarting with the first column up to the last. If some columns should be\nignored, use null for that columns property.\n\n## Configuration\n\nThere are several ways the parser can be configured\n\n### CSVParse Attribute \n\nSettings you can change via the Attribute\n\n#### HasHeader\n\nIf the first line should be ignored, normally because it contains a header, set this Property to `true`, default `false`\n\n```c#\n [Parser.CSVParser(new string[]{nameof(Person.Id), nameof(Person.Name), nameof(Person.Birthdate), nameof(Person.Score)}, HasHeader = true )]\n```\n\n#### SeperatorSymbol\n\nThe symbol that separates the columns. Default `,`\n\n```c#\n [Parser.CSVParser(new string[]{nameof(Person.Id), nameof(Person.Name), nameof(Person.Birthdate), nameof(Person.Score)}, SeperatorSymbol = ';' )]\n```\n\n\n#### QuoteSymbol\n\nThe symbol that sets the quote character. Default `\"`\n\n```c#\n [Parser.CSVParser(new string[]{nameof(Person.Id), nameof(Person.Name), nameof(Person.Birthdate), nameof(Person.Score)}, QuoteSymbol = '\"' )]\n```\n\n\n#### ExtendedLineFeed\n\nNormally the parser will only recognize `U+000A` New Line and `U+000D` Carriage return as line separators.\nIf your CSV file contains uncommon line breaks like `U+0085` *Next Line (Nel)*, you need to enable this setting. Default is `false`.\n\nSupported are\n- `U+0085` *Next Line (Nel)*\n- `U+000C` *Form Feed (FF)*\n- `U+2028` *Line Separator (LS)* **Only when parsing chars**\n- `U+2029` *Paragraph Separator* **Only when parsing chars**\n\n\n### Runtime Options\n\nYou can add a second parameter to the method, to pass several additional\noptions. The generic parameter of the `Option\u003cT\u003e` class must be the same as the\ninput\n\n```c#\ninternal partial IEnumerable\u003cPerson\u003e ParseData(ReadOnlySpan\u003cbyte\u003e data, Parser.Option\u003cbyte\u003e options);\n// or…\ninternal partial IEnumerable\u003cPerson\u003e ParseData(ReadOnlySpan\u003cchar\u003e data, Parser.Option\u003cchar\u003e options);\n```\n\n#### NumberOfElements\n\nTo give the parser a hint how many elements will be parsed, use this setting. It\nwill pass the int in the constructor as only parameter when creating the\ncollection. This normally sets the capacity.\n\n```c#\nParser.Options\u003cchar\u003e options = new() { \n    NumberOfElements = 1_000_000\n};\nParseData(data, options);\n```\n\n#### StringFactory\n\nThis method will be used to create stings from `ReadOnlySpan` (either `byte` or\n`char`). You can use it to define which encoding is used when reading bytes.\nDefault for `bytes` is `UTF8` for `chars` the `ToString()`-Method is called.\n\nYou can also use this factory to deduplicate strings. On large datasets with\nrepeating entries this can speed up time significant.\n\n```c#\nParser.Options\u003cchar\u003e options = new() { \n    StringFactory = System.Text.Encoding.Latin1.GetString\n};\nParseData(data, options);\n```\n\n\n#### OnError\n\nThe parse method should not throw errors. Lines that do not match your\ndefinition, will be ignored. You can register a Callback with the `OnError`\nProperty to be notified every time a row is ignored.\n\nDepending on the Error different classes will be returned. The Type describes\nthe kind of error and hold additional information. E.g. `LineErrorParseError`\nhas ParsedElement that holds the string that could not be parsed (with the\nlimitation that it only works for char data).\n\n```c#\nParser.Options\u003cchar\u003e options = new() { \n    Culture = System.Globalization.CultureInfo.CurrentCulture\n};\nParseData(data, options);\n```\n\n#### Culture\n\nWhen parsing the fields to the configured `CultureInfo` is passed in the parse\nmethod of `ISpanParsable`. Default is the `InvariantCulture`.\n\n```c#\nParser.Options\u003cchar\u003e options = new() { \n    Culture = System.Globalization.CultureInfo.CurrentCulture\n};\nParseData(data, options);\n```\n\n\n### Parse Types that do not implement ISpanParsable and control parsing\n\nIf you need to deserialize a Type that dose not implement the `ISpanParsable`\ninterface or the default parse method provided by it dose not work for you, yod\ncan override the default behavior by adding an additional attribute to the pares method.\n\nTo change the parsing for one property, pass the name of the Property as first argument to `CSVPTransformer`.\n\n```c#\n[Parser.CSVPTransformer(nameof(Person.Birthdate),nameof(ToDate) )]\n```\n\nTo change the parsing for all instances of one types, pass the desired type as first argument to `CSVPTransformer`.\n```c#\n[Parser.CSVPTransformer(typeof(DateOnly),nameof(ToDate) )]\n```\n\nThe second parameter is a method that will be called. It returns the desired object and accepts either `ReadOnlySpan\u003cchar\u003e` or `ReadOnlySpan\u003cbyte\u003e`.\n\nA complete sample\n```c#\n[Parser.CSVParser(nameof(Person.Id), nameof(Person.Name), nameof(Person.Birthdate), nameof(Person.Score))]\n[Parser.CSVPTransformer(nameof(Person.Birthdate),nameof(ToDate) )]\npublic static partial IEnumerable\u003cPerson\u003e ParseData(ReadOnlySpan\u003cchar\u003e data);\n\nprivate static DateOnly ToDate(ReadOnlySpan\u003cchar\u003e data)\n{\n    return DateOnly.ParseExact(data, \"dd-MM-yyyy\");\n}\n```\n\n\n","funding_links":[],"categories":["Do not want to test 112 ( old ISourceGenerator )","Source Generators"],"sub_categories":["1. [ThisAssembly](https://ignatandrei.github.io/RSCG_Examples/v2/docs/ThisAssembly) , in the [EnhancementProject](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#enhancementproject) category","Serialization"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLokiMidgard%2FCSV-Parser-Generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FLokiMidgard%2FCSV-Parser-Generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLokiMidgard%2FCSV-Parser-Generator/lists"}