{"id":13822547,"url":"https://github.com/pheki/rudano","last_synced_at":"2026-03-11T03:03:56.137Z","repository":{"id":57664062,"uuid":"288293473","full_name":"pheki/rudano","owner":"pheki","description":"A data serialization format as similar as possible to Rust's own syntax","archived":false,"fork":false,"pushed_at":"2022-12-16T19:45:38.000Z","size":76,"stargazers_count":44,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-20T14:25:37.956Z","etag":null,"topics":["hacktoberfest","rudano","rust","rust-crate","serde"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pheki.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-08-17T21:49:57.000Z","updated_at":"2025-03-27T23:00:20.000Z","dependencies_parsed_at":"2023-01-29T15:46:02.137Z","dependency_job_id":null,"html_url":"https://github.com/pheki/rudano","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pheki/rudano","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pheki%2Frudano","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pheki%2Frudano/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pheki%2Frudano/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pheki%2Frudano/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pheki","download_url":"https://codeload.github.com/pheki/rudano/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pheki%2Frudano/sbom","scorecard":{"id":730821,"data":{"date":"2025-08-11","repo":{"name":"github.com/pheki/rudano","commit":"cc15139d4562c9e98b26f8979e930b2634444a97"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Code-Review","score":0,"reason":"Found 1/16 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE-APACHE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T14:21:41.313Z","repository_id":57664062,"created_at":"2025-08-22T14:21:41.313Z","updated_at":"2025-08-22T14:21:41.313Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30368622,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T21:41:54.280Z","status":"online","status_checked_at":"2026-03-11T02:00:07.027Z","response_time":84,"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":["hacktoberfest","rudano","rust","rust-crate","serde"],"created_at":"2024-08-04T08:02:05.498Z","updated_at":"2026-03-11T03:03:56.087Z","avatar_url":"https://github.com/pheki.png","language":"Rust","funding_links":[],"categories":["Rust"],"sub_categories":[],"readme":"# Rudano\n\n[![Build Status](https://travis-ci.org/pheki/rudano.svg?branch=master)](https://travis-ci.org/pheki/rudano)\n[![Crate](https://img.shields.io/crates/v/rudano.svg)](https://crates.io/crates/rudano)\n[![API](https://docs.rs/rudano/badge.svg)](https://docs.rs/rudano)\n[![Minimum rustc version](https://img.shields.io/badge/rustc-1.40+-green.svg)](https://github.com/pheki/rudano#rust-version-support)\n\nRudano, Rust Data Notation, is a data serialization format designed to be as\nsimilar as possible to Rust's own syntax.\n\n# Why?\n\nWhile I really like [RON](https://github.com/ron-rs/ron), I find that syntax\ndifferences make it confusing when you're switching contexts between it and Rust\na lot, specially as () are used for structs.\n\nThat's why I created Rudano, with the focus on being very similar to Rust's\nliteral notation itself, so that you can just write your \"object\" descriptions\nusing the same syntax you're already used to.\n\nThe exception is maps, which do not have a literal syntax in Rust, and have been\nchosen to be delimited with `[]`. Its explained why in [its spec](#map).\n\n# Example and Comparison\n\nConsider the following imaginary rust structure:\n\n```rust\n#[derive(Serialize, Deserialize)]\nenum Ip {\n    V4(u8, u8, u8, u8),\n    V6(u8, u8, u8, u8, u8, u8, u8, u8),\n}\n\n#[derive(Serialize, Deserialize)]\nstruct Network {\n    name: String,\n    local_address: Ip,\n    hosts: HashMap\u003cString, Ip\u003e,\n}\n```\n\nAn example of this structure in Rudano:\n\n```rust\n// Struct name is required (see why below)\nNetwork {\n    name: \"Local Network\",\n    // Enums are supported\n    local_address: V4(192, 168, 0, 100),\n    hosts: [\n        \"Foo\": V6(0, 0, 0, 0, 0, 0, 0, 0xA3),\n        \"Bar\": V4(192, 168, 0, 104),\n    ], // Trailing comma is allowed\n}\n```\n\nSame example in Ron:\n\n```\n// Struct name is optional\nNetwork (\n    name: \"Local Network\",\n    // Enums are supported\n    local_address: V4(192, 168, 0, 100),\n    hosts: {\n        \"Foo\": V6(0, 0, 0, 0, 0, 0, 0, 0xA3),\n        \"Bar\": V4(192, 168, 0, 104),\n    }, // Trailing comma is allowed\n)\n```\n\nIn JSON, comments are not allowed, but I hope it speaks by itself:\n\n```\n{\n    \"name\": \"Local Network\",\n    \"local_address\": {\n        \"V4\": [192, 168, 0, 100]\n    },\n    \"hosts\": {\n        \"Foo\": {\n            \"V6\": [0, 0, 0, 0, 0, 0, 0, 0xA3]\n        },\n        \"Bar\": {\n            \"V4\": [192, 168, 0, 104]\n        }\n    }\n}\n```\n\n|         | Rudano |  RON  |  JSON  |\n| ------- | :----: | :---: | :----: |\n| Comments | // | // and /* */ | Not allowed |\n| Structs | Name { property: value } | Name ( property: value ) | { \"property\": value } |\n| Arrays | [value] | [value] | [value] |\n| Maps | [key: value] | { key: value } | { key: value } |\n| Enums | Variant(data) | Variant(data) | { \"Variant\": data } |\n| Trailing Comma | Allowed | Allowed | Not allowed |\n\n# Contributing\n\nAny question, bug report, suggestion or pull request is welcome! Just open an\nissue or PR.\n\n# Stability\n\nUnstable, the format itself may change to fix ambiguity issues and conform\nbetter to Rust's syntax, using semver for breaking changes.\n\n# Caveats\n\n- Zero-copy deserialization with borrowed strings will fail if escape codes are\nused. (I believe it's also true for any other format)\n\n# Why are struct names required?\n\nAs structs names are required in the format, structs can be later converted into\nan enum variant without breaking backward compatibility. For example, when using\n\n```rust\nstruct Point { position: (i32, i32), name: String }\n\nenum Object {\n    Point { position: (i32, i32), name: String },\n    Canvas { size: (i32, i32) }\n}\n```\n\nThe serialized value `Point { position: (10, 20), \"Great Point!\" }` is valid\nboth as a `Point` and an `Object`. This is valid for all struct types and their\nequivalent enum variants (Unit, NewType, Tuple and Struct).\n\n# Rust version support\n\nThe MSRV is **1.40 or greater** and it's tested with 1.40.0, stable, beta and\nnightly. Changing it will only be done in a minor (0.x) or greater release.\n\n# Data Types\n\nNotice that in all examples with definitions, `#[derive(Serialize, Deserialize)]` is omitted for brevity.\n\n## Bool\n\nBool types may be either the literals `true` or `false`.\n\n### Examples\n\n- `true`\n- `false`\n\n## Signed Integers\n\nSigned integers includes i8, i16, i32, i64, and i128. They start with `-` if they are negative, but not `+` if they're positive. `_` (underscores) in the number are ignored and they may be written in hexadecimal, octal or binary form, by using the prefixes `0x`, `0o`, or `0b` respectively.\n\n### Examples\n\nFor i16:\n\n- `27`\n- `43`\n- `0x2A`\n- `-0x1F`\n- `0b11010`\n- `-37`\n- `-32768`\n- `32767`\n\n## Unsigned integers\n\nUnsigned integers includes u8, u16, u32, u64, and u128. They do not support `-` or `+`. `_` (underscores) in the number are ignored and they may be written in hexadecimal, octal or binary form, by using the prefixes `0x`, `0o`, or `0b` respectively.\n\n### Examples\n\nFor u16:\n\n- `27`\n- `43`\n- `0x2A`\n- `0b11010`\n- `0`\n- `65535`\n\n## Floats\n\nFloat types includes f32 and f64, and they are not yet fully specified.\n\n### Examples\n\nFor f32:\n\n- `27`\n- `43.0`\n- `239.34`\n- `-37.3`\n- `-37.0E+12`\n- `-92`\n- `inf`\n- `-inf`\n\n## Char\n\nChar types are delimited by `''` and may include any character or escape code as defined in [the reference](https://doc.rust-lang.org/reference/tokens.html?highlight=escape#character-and-string-literals).\n\n### Examples\n\n- `'a'`\n- `'@'`\n- `'\\x5A'`\n- `'\\u{bf0}'`\n- `'\\u{1f638}'`\n- `'😸'`\n- `'\\n'`\n- `'\\t'`\n- `'\\u{10ffff}'`\n- `'\\u{fffd}'`\n\n## String\n\nString types are delimited by `\"\"` and may include any character or escape code as defined in [the reference](https://doc.rust-lang.org/reference/tokens.html?highlight=escape#character-and-string-literals).\n\n### Examples\n\n- `\"a\"`\n- `\"@\"`\n- `\"The quick brown fox jumps over the lazy dog\"`\n- `\"\\x5A\"`\n- `\"\\u{bf0}\\u{1f638}\"`\n- `\"😸\"`\n- `\"such\\nwow\"`\n- `\"very\\tlol\"`\n- `\"\\u{10ffff}\"`\n- `\"\\u{fffd}\"`\n\n## Option\n\nOptions types have two possiblities: it may be the identifier `None` or the identifier `Some`, which includes parenthesis and a value after.\n\n### Examples\n\n- `None`\n- `Some(())`\n- `Some(30)`\n\n## Unit\n\nUnit types include only a single possible value: `()`.\n\nExample:\n\n- `()`\n\n## Unit Struct\n\nUnit struct is a named value with a single value: the struct itself. It is expressed as the struct name and optionally empty curly braces (`{}`).\n\n### Examples\n\nDefinition\n\n`struct Unit;`\n\nSerialized\n\n- `Unit`\n- `Unit {}`\n\n## Newtype Struct\n\nNewtype structs are structs with a single, unnamed field. It is represented by the struct name, parenthesis and the value. It is actually a specific case of a tuple struct. If you want it to be represented by just its internal value, use [`#[serde(transparent)]`](https://serde.rs/container-attrs.html#transparent).\n\n### Examples\n\nDefinition\n\n```rust\nstruct Newtype(u8);\n```\n\nSerialized\n\n- `Newtype(39)`\n- `Newtype(0xa8)`\n\nDefinition\n\n```rust\n#[serde(transparent)]\nstruct Transparent(String);\n```\n\nSerialized\n\n- `\"yay\"`\n- `\"it works!\"`\n\n## Tuple Struct\n\nTuples structs are structs with multiple unnamed fields, akin to named tuples. Its represented by the struct name and the values inside parenthesis.\n\n### Example\n\nDefinition\n\n```rust\nstruct TupleStruct(u8, char);\n```\n\nSerialized\n\n- `TupleStruct(10, 'a')`\n\n## Struct\n\nStructs are structs with named fields. Represented by struct name, followed by curly braces and comma separated `identifier: value` pairs. Trailing comma is allowed (and recommended for multi-line).\n\n### Example\n\nDefinition\n\n```rust\nstruct Point { position: (i32, i32), name: String }\n```\n\nSerialized\n\n- `Point { position: (10, 20), \"Great Point!\" }`\n\n## Enum Variants\n\nThe enum variants are serialized and deserialized exactly the same as their struct counterparts. The variant types are: Unit, NewType, Tuple and Struct.\n\n### Example\n\nDefinition\n\n```\nenum Enum {\n    Unit,\n    Newtype(u32),\n    Tuple(u32, u32),\n    Struct {\n        a: u32,\n    },\n}\n\nstruct Variants {\n    unit: Enum,\n    newtype: Enum,\n    tuple: Enum,\n    struct_variant: Enum,\n}\n```\n\nSerialized structs with all variants:\n\n```rust\nVariants {\n    unit: Unit,\n    newtype: Newtype(70),\n    tuple: Tuple(20, 80),\n    struct_variant: Struct {\n        a: 10,\n    },\n}\n```\n## Sequence (or array)\n\nAn array is a contiguous sequence of elements of the same type. Represented by a comma-separated list of its elements surounded by square braces. Automatically derived by serde for Vec, can actually be used for arrays by adding #[serde(serialize_with = \"rudano::serialize_array\")] to the field definition.\n\n### Example\n\n- `[10, 20, 30]`\n- `[\"abc\", \"wow\"]`\n\n## Map\n\nAn map is a set of (key, value) pairs. Represented by sequence of comma-separated pairs, each pair having a colon (`:`) between its key and its value. Automatically derived by serde for HashMap and other std map types.\n\n### Example\n\nDefinition\n\n`HashMap\u003cString, i32\u003e`\n\nSerialized\n\n- `[\"x\": 10, \"y\": 20]`\n- `[\"blue\": 21, \"red\": 22]`\n\nDefinition\n\n`HashMap\u003ci32, String\u003e`\n\n- `[1: \"One\"]`\n- `[13: \"Too high\"]`\n\n### Rationale\n\nMaps are delimited in rudano with `[]`. The reason is that maps are homogeneous\nstructures (like arrays, but unlike structures) and they can actually be\ninitialized in Rust code with `[(key0, value0), (key1, value1)].collect()`,\nwhich is similar to RuDaNo's `[key0: value0, key1: value1]`. It also makes maps\ndifferent than structs, which was one of RON's original motivations.\n\n# Differences with Rust's Syntax\n\nThese differences are intentional (but subject to discussion):\n- Float types without decimal point are allowed\n- `NaN`, `inf` and `-inf` are represented as such (its how rustc prints them), even though they're not valid literals.\n- Numbers with type suffixes are not supported (e.g. 15u64)\n- Vecs are serialized as `[1, 2, 3]`, not `vec![1, 2, 3]`\n- Arrays are serialized as tuples by default (because that's the default Serialize impl). Using `#[serde(serialize_with = \"rudano::serialize_array\")]` will make it serialize using array notation (as an `[]` sequence)\n\n# License\n\nThis crate (library) is distributed under terms of MIT license or Apache License (Version 2.0), at your option.\nSee `LICENSE-MIT` and `LICENSE-APACHE` for terms.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpheki%2Frudano","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpheki%2Frudano","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpheki%2Frudano/lists"}