{"id":20266358,"url":"https://github.com/tecc/serry","last_synced_at":"2025-09-03T20:50:39.919Z","repository":{"id":172543739,"uuid":"647512740","full_name":"tecc/serry","owner":"tecc","description":"The unstructured Serde.","archived":false,"fork":false,"pushed_at":"2024-01-27T04:12:48.000Z","size":113,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"dev","last_synced_at":"2025-06-07T01:46:42.607Z","etag":null,"topics":["deserialization","rust","rust-lang","serialization"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tecc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2023-05-31T00:20:33.000Z","updated_at":"2024-01-24T03:15:12.000Z","dependencies_parsed_at":null,"dependency_job_id":"950f745a-3c96-49d7-bd07-0db8f8d2b6a1","html_url":"https://github.com/tecc/serry","commit_stats":null,"previous_names":["tecc/serry"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/tecc/serry","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tecc%2Fserry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tecc%2Fserry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tecc%2Fserry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tecc%2Fserry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tecc","download_url":"https://codeload.github.com/tecc/serry/tar.gz/refs/heads/dev","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tecc%2Fserry/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273509142,"owners_count":25118447,"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-09-03T02:00:09.631Z","response_time":76,"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":["deserialization","rust","rust-lang","serialization"],"created_at":"2024-11-14T12:08:49.622Z","updated_at":"2025-09-03T20:50:39.889Z","avatar_url":"https://github.com/tecc.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Serry - the unstructured Serde\n\n\u003e NOTE: \n\u003e \n\u003e Serry's API and data representations are somewhat unstable. \n\u003e They may be subject to breaking changes.\n\nSerde is a great library, but can sometimes be undesirable - it demands you use an abstract but structured view of your data such that it may be serialised into virtually any format.\n\nSerry is different - it is a serialisation and deserialisation library that explicitly _does **not** specify_ a format for its consumers - it leaves the specifics of serialisation and deserialisation up to each type to implement.\nThe only things Serry does is provide some common facilities and utilities to serialise data.\n\n## Usage\n\nThe main traits used in Serry are the `SerryRead` and `SerryWrite` traits.\nAs the names suggest, those traits are responsible for the reading and writing of your data (respectively comparable to `Deserialize` and `Serialize`).\nThe `SerrySized` trait also exists as a utility.\n\n### Derive macros\n\nSerry has a `derive` feature very similar to Serde's equivalent.\nIt is configurable, although everything comes with a sensible default.\n\n```rust\n// Data is packed tightly in Serry, so there's no information describing\n// \"this is the `name` field\" nor \"this is the `password` field\".\n// By default, Serry will effectively \"concatenate\" the fields when serialising.\n#[derive(SerryRead, SerryWrite, SerrySized)]\nstruct User {\n    name: String,\n    // Let's pretend this is hashed and secure and all that.\n    password: String,\n    tasks: Vec\u003c(String, TaskState)\u003e // Also, yes, some tuples are supported.\n}\n\n/// Enumerators are stored similarly to structs in that each variant \n/// is treated like one in practice.\n/// The *only* difference is that they have a 'hidden field' of sorts;\n/// that field being the discriminant. \n/// The discriminant is written before the variant contents. \n/// It is by default represented as a u16, although that can be changed with the repr attribute.\n#[derive(SerryRead, SerryWrite, SerrySized)]\nenum TaskState {\n    NotYetStarted,\n    Started {\n        started_at: std::time::SystemTime \n    },\n    /// If you wish to change the discriminant of a single variant,\n    /// you can do so with the `repr` value.\n    /// Any expression can be used as long as the expressions can be evaluated\n    /// in a const context.\n    #[serry(repr(8))]\n    Completed {\n        started_at: std::time::SystemTime,\n        completed_at: std::time::SystemTime\n    }\n}\n/// The discriminant type can be changed as well. \n/// Serry provides builtin support for integer types and strings as discriminants.\n/// If strings are used, the discriminants default to \n/// using their respective variant names as the discriminants.\n#[derive(SerryRead, SerryWrite, SerrySized)]\n#[serry(repr(String))]\nenum ThemePreference {\n    Light,\n    Dark,\n    #[serry(repr(\"auto\"))]\n    Auto\n}\n```\n\n### Implementing the traits manually\n\nManually implementing the traits can be benificial in some cases, but for \nmost purposes derive macros are preferred due to the greater clarity they provide.\n\nAs an example, take Serry's `bool` implementation:\n```rust \nconst BOOL_FALSE: u8 = 0;\nconst BOOL_TRUE: u8 = 1;\n\nimpl SerryRead for bool {\n    fn serry_read(input: \u0026mut impl SerryInput) -\u003e ReadResult\u003cSelf\u003e {\n        let value = input.read_value::\u003cu8\u003e()?;\n        match value {\n            BOOL_FALSE =\u003e Ok(false),\n            BOOL_TRUE =\u003e Ok(true),\n            _ =\u003e Err(SerryError::custom(format!(\n                \"bool is invalid - {} is not {} (false) nor {} (true)\",\n                value, BOOL_FALSE, BOOL_TRUE\n            ))),\n        }\n    }\n}\nimpl SerryWrite for bool {\n    fn serry_write(\u0026self, output: \u0026mut impl SerryOutput) -\u003e WriteResult\u003c()\u003e {\n        output.write_value(if *self { BOOL_TRUE } else { BOOL_FALSE })\n    }\n}\nimpl SerrySized for bool {\n    #[inline]\n    fn predict_size(\u0026self) -\u003e usize {\n        Self::predict_constant_size_unchecked()\n    }\n    #[inline]\n    fn predict_constant_size() -\u003e Option\u003cusize\u003e {\n        Some(Self::predict_constant_size_unchecked())\n    }\n    #[inline]\n    fn predict_constant_size_unchecked() -\u003e usize {\n        std::mem::size_of::\u003cu8\u003e()\n    }\n}\n```\n\n`SerryRead` for `bool` is quite simple: it reads a single byte (`u8`) and checks if it is `0u8` (false) or `1u8` (true).\n\nReally, just use the library. It can't hurt that much.\n\n## Data representations\n\nAll Serry-provided representations attempt to be somewhat parseable by non-Rust programs.\n\n### Integers\n\nIntegers are represented in little-endian (this may be subject to change, but probably will not).\n\n### Vectors (for `T`)\n\nVectors begin with a `u64` which determines its length.\nThen, Serry will read _n_ amount of `T`s into a vector. \n\n### HashMap (for `K` and `V`)\n\nHashMaps are internally represented effectively as Vectors of `(K, V)`.\nThis means that you could interpret the encoded data as a list of entries or as a map of keys to values.\n\nNote that Serry makes _no_ guarantee regarding the order of the elements. If a predictable order is desirable, please use vectors.\n\n### Strings\n\nStrings are effectively represented as Vectors of `u8`. They are encoded as UTF-8.\nThe only difference between using Vec\u003cu8\u003e and Strings is that `String` guarantees a valid UTF-8 string.\n\nSimilar implementations are used for `OsStr`, `Path`, and their owned counterparts;\nthe exact details _may_ vary based on the operating system.\n\n## Licence\n\n```txt\n   Copyright (c) 2023 tecc\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftecc%2Fserry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftecc%2Fserry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftecc%2Fserry/lists"}