{"id":13590810,"url":"https://github.com/dezhidki/Tommy","last_synced_at":"2025-04-08T14:31:50.297Z","repository":{"id":34570097,"uuid":"173182312","full_name":"dezhidki/Tommy","owner":"dezhidki","description":"A single-file TOML reader and writer for C#","archived":false,"fork":false,"pushed_at":"2022-04-13T08:37:15.000Z","size":436,"stargazers_count":195,"open_issues_count":13,"forks_count":15,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-07-16T17:38:14.047Z","etag":null,"topics":["csharp","dotnet","single-file","toml","toml-parser"],"latest_commit_sha":null,"homepage":null,"language":"C#","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/dezhidki.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":"2019-02-28T20:26:47.000Z","updated_at":"2024-07-10T14:20:55.000Z","dependencies_parsed_at":"2022-08-23T16:00:25.150Z","dependency_job_id":null,"html_url":"https://github.com/dezhidki/Tommy","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dezhidki%2FTommy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dezhidki%2FTommy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dezhidki%2FTommy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dezhidki%2FTommy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dezhidki","download_url":"https://codeload.github.com/dezhidki/Tommy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":213354642,"owners_count":15574576,"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":["csharp","dotnet","single-file","toml","toml-parser"],"created_at":"2024-08-01T16:00:50.717Z","updated_at":"2024-08-01T16:05:36.187Z","avatar_url":"https://github.com/dezhidki.png","language":"C#","funding_links":[],"categories":["C# #"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n    \u003cimg src=\"logos/tommy_logo.png\" height=\"200\" /\u003e\n\u003c/p\u003e\n\n![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/dezhidki/Tommy?style=flat-square)\n[![Nuget](https://img.shields.io/nuget/dt/Tommy?label=NuGet\u0026style=flat-square)](https://www.nuget.org/packages/Tommy)\n\n# Tommy\n\nTommy is a single-file TOML reader and writer for C#.  \nThis library is meant for small, cross-platform projects that want support the most .NET versions possible.\n\nTo use it, simply include [Tommy.cs](Tommy/Tommy.cs) into your project and you're done!\n\nAlternatively, you can obtain the prebuilt package from [NuGet](https://www.nuget.org/packages/Tommy)!\n\n## Features\n\n* Full implementation of TOML 1.0.0 spec.\n* Parser implemented with `TextReader` for simplicity and vast input support (i.e. string inputs with `StringReader`, streams via `StreamReader`, etc).\n* Parses TOML into a node-based structure that is similar to [SimpleJSON](https://github.com/Bunny83/SimpleJSON).\n* Basic support for parsing and saving comments.\n* Supports .NET 3.5+, Mono, .NET Core!\n* Uses C# 9 syntax for smaller file size.\n* Small footprint (~41 KB compiled) compared to other similar C# libraries.\n* Performs well compared to other similar C# libraries ([view benchmarks](https://github.com/bugproof/TomlLibrariesBenchmark))\n\n### Extensions\n\nTommy includes only a reader and a writer. There exist a few additional extensions that you can use\n\nOfficially maintained\n* [Tommy.Extensions](https://www.nuget.org/packages/Tommy.Extensions) -- General helper extensions for Tommy\n* [Tommy.Extensions.Configuration](https://www.nuget.org/packages/Tommy.Extensions.Configuration) -- `Microsoft.Extensions.Configuration` integration for Tommy\n\n3rd party\n* [Tommy.Serializer](https://github.com/instance-id/Tommy.Serializer) -- (De)serialization of objects for Tommy\n\n## How to use\n\n### Parsing TOML file\n\nThe TOML file:\n\n```toml\ntitle = \"TOML Example\"\n\n[owner]\nname = \"Tom Preston-Werner\"\ndob = 1979-05-27T07:32:00-08:00\n\n[database]\nserver = \"192.168.1.1\"\nports = [ 8001, 8001, 8002 ]\nconnection_max = 5000\nenabled = true\n```\n\n```csharp\n// Reference the Tommy namespace at the start of the file\nusing Tommy;\n\n\n// Parse into a node\nusing(StreamReader reader = File.OpenText(\"configuration.toml\"))\n{\n    // Parse the table\n    TomlTable table = TOML.Parse(reader);\n\n    Console.WriteLine(table[\"title\"]);  // Prints \"TOML Example\"\n\n    // You can check the type of the node via a property and access the exact type via As*-property\n    Console.WriteLine(table[\"owner\"][\"dob\"].IsDateTime)  // Prints \"True\"\n\n    // You can also do both with C# 7 syntax\n    if(table[\"owner\"][\"dob\"] is TomlDate date)\n        Console.WriteLine(date.OnlyDate); // Some types contain additional properties related to formatting\n\n    // You can also iterate through all nodes inside an array or a table\n    foreach(TomlNode node in table[\"database\"][\"ports\"])\n        Console.WriteLine(node);\n}\n```\n\nNote that `TOML.Parse` is just a shorthand for creating a `TOMLParser` object and parsing it. In essence, `TOML.Parse` is just simply a wrapper for the following code block:\n\n```csharp\nTomlTable table;\nusing(TOMLParser parser = new TOMLParser(reader))\n    table = parser.Parse();\n```\n\nIn some cases, you might want to write the snippet manually, since the TOML parser can contain some additional parsing options.\n\n### Catching parse errors\n\nTommy is an optimistic parser: when it encounters a parsing error, it does not stop the parsing process right away. \nInstead, Tommy logs all parsing errors and throws them as a single `TomlParseException`. In addition to parsing errors, \nthe exception object also contains the *partially parsed* TOML file that you can still attempt to use at your own risk.\n\nHere's an example of handling parsing errors:\n\n```csharp\nTomlTable table;\n\ntry\n{\n    // Read the TOML file normally.\n    table = TOML.Parse(reader);\n} catch(TomlParseException ex) \n{\n    // Get access to the table that was parsed with best-effort.\n    table = ex.ParsedTable;\n\n    // Handle syntax error in whatever fashion you prefer\n    foreach(TomlSyntaxException syntaxEx in ex.SyntaxErrors)\n        Console.WriteLine($\"Error on {syntaxEx.Column}:{syntaxEx.Line}: {syntaxEx.Message}\");\n}\n```\n\nIf you do not wish to handle exceptions, you can instead use [`TommyExtensions.TryParse()`](Tommy/TommyExtensions.cs#L21).\n\n## Generating or editing a TOML file\n\nTommy supports implicit casting from most built-in types to make file generation easy.\n\n```csharp\n// Reference the Tommy namespace at the start of the file\nusing Tommy;\n\n\n// Generate a TOML file programmatically\nTomlTable toml = new TomlTable \n{\n    [\"title\"] = \"TOML Example\",\n    // You can also insert comments before a node with a special property\n    [\"value-with-comment\"] = new TomlString\n    {\n        Value = \"Some value\",\n        Comment = \"This is just some value with a comment\"\n    },\n    // You don't need to specify a type for tables or arrays -- Tommy will figure that out for you\n    [\"owner\"] = \n    {\n        [\"name\"] = \"Tom Preston-Werner\",\n        [\"dob\"] = DateTime.Now\n    },\n    [\"array-table\"] = new TomlArray \n    {\n        // This is marks the array as a TOML array table\n        IsTableArray = true,\n        [0] = \n        {\n            [\"value\"] = 10\n        },\n        [1] = \n        {\n            [\"value\"] = 20\n        }\n    },\n    [\"inline-table\"] = new TomlTable\n    {\n        IsInline = true,\n        [\"foo\"] = \"bar\",\n        [\"bar\"] = \"baz\",\n        // Implicit cast from TomlNode[] to TomlArray\n        [\"array\"] = new TomlNode[] { 1, 2, 3 }\n    }\n};\n\n\n// You can also define the toml file (or edit the loaded file directly):\ntoml[\"other-value\"] = 10;\ntoml[\"value with spaces\"] = new TomlString \n{\n    IsMultiline = true,\n    Value = \"This is a\\nmultiline string\"\n};\n\n// Write to a file (or any TextWriter)\n// You can forcefully escape ALL Unicode characters by uncommenting the following line:\n// TOML.ForceASCII = true;\nusing(StreamWriter writer = File.CreateText(\"out.toml\"))\n{\n    toml.WriteTo(writer);\n    // Remember to flush the data if needed!\n    writer.Flush();\n}\n```\n\nThe above code outputs the following TOML file:\n\n```toml\ntitle = \"TOML Example\"\n# This is just some value with a comment\nvalue-with-comment = \"Some value\"\ninline-table = { foo = bar, bar = baz, array = [ 1, 2, 3, ], }\nother-value = 10\n\"value with spaces\" = \"\"\"This is a\nmultiline string\"\"\"\n\n[owner]\nname = \"Tom Preston-Werner\"\ndob = 2019-02-28 22:08:56\n\n[[array-table]]\nvalue = 10\n\n[[array-table]]\nvalue = 20\n```\n\n### Collapsed values\n\nTommy supports collapsed values (i.e. values with keys of the form `foo.bar`). For that, simply set the `CollapseLevel` property of a value node.  \nBy default, the collapse level for each TOML node is `0`, which means that the node will appear under the table you define it in. \nSetting collapse level one value higher will move the value one table higher in the hierarchy.\n\nIn other words, if you define the following table:\n\n```csharp\nTomlTable table = new TomlTable {\n    [\"foo\"] = new TomlTable {\n        [\"bar\"] = new TomlTable {\n            [\"baz\"] = new TomlString {\n                Value = \"Hello, world!\"\n            }\n        }\n    }\n};\n```\n\nWill output the TOML file:\n\n```toml\n[foo.bar]\nbaz = \"Hello, world!\"\n```\n\nAdding `CollapseLevel = 1` to `foo.bar.baz` will \"collapse\" the key by one level:\n\n```csharp\nTomlTable table = new TomlTable {\n    [\"foo\"] = new TomlTable {\n        [\"bar\"] = new TomlTable {\n            [\"baz\"] = new TomlString {\n                CollapseLevel = 1, // Here we collapse the foo.bar.baz by one level\n                Value = \"Hello, world!\"\n            }\n        }\n    }\n};\n```\n\n```toml\n[foo]\nbar.baz = \"Hello, world!\"\n```\n\n### Some notes about the writer\n\n* **The writer does not currently preserve the layout of the original document!** This is to save size and keep things simple for now.\n* Check out [Style info](./style.md) for information on what style Tommy uses to output TOML\n* The writer only uses basic strings for complex keys (i.e. no literal strings).\n\n## Optional extensions\n\nIn addition to main functionality, Tommy includes *optional* extensions located in [TommyExtensions.cs](Tommy/TommyExtensions.cs). \nThe file is a collection of various functions that you might find handy, like `TOMLParser.TryParse`.\n\nTo use the extensions, simply include the file in your project. The extension methods will appear in types they are defined for.\n\n## Tests\n\nTommy's parser is tested against [toml-lang/compliance](https://github.com/toml-lang/compliance) test suite with additions from [pyrmont/toml-specs](https://github.com/pyrmont/toml-specs).\n\n## What's with the name?\n\n[Because TOML sounded like Tommy, hahaha](https://i.ytimg.com/vi/y9N1GV88T7g/maxresdefault.jpg)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdezhidki%2FTommy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdezhidki%2FTommy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdezhidki%2FTommy/lists"}