Rusty Object Notation

Overview

Rusty Object Notation

Build Status Crates.io MSRV Docs Gitter

RON is a simple readable data serialization format that looks similar to Rust syntax. It's designed to support all of Serde's data model, so structs, enums, tuples, arrays, generic maps, and primitive values.

Example

GameConfig( // optional struct name
    window_size: (800, 600),
    window_title: "PAC-MAN",
    fullscreen: false,
    
    mouse_sensitivity: 1.4,
    key_bindings: {
        "up": Up,
        "down": Down,
        "left": Left,
        "right": Right,
        
        // Uncomment to enable WASD controls
        /*
        "W": Up,
        "A": Down,
        "S": Left,
        "D": Right,
        */
    },
    
    difficulty_options: (
        start_difficulty: Easy,
        adaptive: false,
    ),
)

Why RON?

Example in JSON

{
   "materials": {
        "metal": {
            "reflectivity": 1.0
        },
        "plastic": {
            "reflectivity": 0.5
        }
   },
   "entities": [
        {
            "name": "hero",
            "material": "metal"
        },
        {
            "name": "monster",
            "material": "plastic"
        }
   ]
}

Notice these issues:

  1. Struct and maps are the same
    • random order of exported fields
      • annoying and inconvenient for reading
      • doesn't work well with version control
    • quoted field names
      • too verbose
    • no support for enums
  2. No trailing comma allowed
  3. No comments allowed

Same example in RON

Scene( // class name is optional
    materials: { // this is a map
        "metal": (
            reflectivity: 1.0,
        ),
        "plastic": (
            reflectivity: 0.5,
        ),
    },
    entities: [ // this is an array
        (
            name: "hero",
            material: "metal",
        ),
        (
            name: "monster",
            material: "plastic",
        ),
    ],
)

The new format uses (..) brackets for heterogeneous structures (classes), while preserving the {..} for maps, and [..] for homogeneous structures (arrays). This distinction allows us to solve the biggest problem with JSON.

Here are the general rules to parse the heterogeneous structures:

class is named? fields are named? what is it? example
no no tuple (a, b)
yes/no no tuple struct Name(a, b)
yes no enum value Variant(a, b)
yes/no yes struct (f1: a, f2: b,)

Specification

There is a very basic, work in progress specification available on the wiki page. A more formal and complete grammar is available here.

Appendix

Why not XML?

  • too verbose
  • unclear how to treat attributes vs contents

Why not YAML?

  • significant white-space
  • specification is too big

Why not TOML?

  • alien syntax
  • absolute paths are not scalable

Why not XXX?

  • if you know a better format, tell me!

Tooling

IntelliJ: https://github.com/ron-rs/intellij-ron

VS Code: https://github.com/a5huynh/vscode-ron

Sublime Text: https://packagecontrol.io/packages/RON

Atom: https://atom.io/packages/language-ron

Vim: https://github.com/ron-rs/ron.vim

EMACS: https://chiselapp.com/user/Hutzdog/repository/ron-mode/home

License

RON is dual-licensed under Apache-2.0 and MIT.

Comments
  • Integer support

    Integer support

    Roughly following the discussion from https://github.com/ron-rs/ron/issues/47 and related issues and PRs, this PR extends the Number type (and so indirectly the Value type) to support integers. I hope I didn't grossly misunderstand the discussion there, but I am keen to make adjustments here to make the project better.

    ~~I tried to limit the impact to the API to a single breaking change by extending the already opaque Number type rather than the Value enum which exposes its structure. The breaking change is that the get method in Number is replaced by as_f64 and as_i64 for getting the appropriate type.~~ Since Integer and Float types are distinct, they will not be ordered by value (as explained below). This is a breaking change in itself.

    To maintain the traits on Number, Integers are simply ordered before Floats. This makes float and integer not comparable in value (e.g. Number::Integer(2) < Number::Float(Float(1.0))) because I didn't see any necessity to do so, but I'm open to suggestions.

    The tests are adjusted to verify that both integers and floats are working.

    opened by elrnv 20
  • Port `ser::Serializer` to `io::Write`

    Port `ser::Serializer` to `io::Write`

    Makes the Serializer struct generic over io::Write, allowing it to be used with more types (and less allocation). As a side-effect, the trailing commas are also removed from the output.

    This was a quick implementation, written in response to compiler messages, so it could probably do with some cleaning up. It might be a good time to approach #175

    Closes #202

    TODO

    • [ ] Update docs
    opened by Plecra 17
  • Ergonomics of optional fields

    Ergonomics of optional fields

    If I have a struct like

    #[derive(Debug, Clone, Deserialize)]
    pub struct Settings {
        pub font: Option<PathBuf>, // <- optional field
        pub other_value: u8,
    }
    

    I can omit the field in .ron file to get None:

    (
        other_value: 0,
    )
    

    But I'm forced to write Some() around the actual value which clutters up the config:

    (
        font: Some("OpenSans-Regular.ttf"), // :(
        // font: "OpenSans-Regular.ttf", // I want this
        other_value: 0,
    )
    

    Seems like an ergonomic problem to me :(

    See https://gitter.im/ron-rs/ron?at=59d228bd614889d47565733d

    opened by ozkriff 15
  • Skipping brackets on the top level structure

    Skipping brackets on the top level structure

    Would it be possible/reasonable to skip the surrounding (), {}, or [] on the top level structure in document? As it is a config needs to be saved as something like:

    (
        player_name: "abc",
        foo: 5,
        bar: [
            1,
            5,
            22,
        ],
    )
    

    It'd be a lot cleaner to my mind if we could skip the surrounding brackets and just write it as:

    player_name: "abc",
    foo: 5,
    bar: [
        1,
        5,
        22,
    ],
    
    enhancement help wanted 
    opened by halvnykterist 14
  • Use base64 for `serde_bytes` annotated fields

    Use base64 for `serde_bytes` annotated fields

    With the following struct, small will be represented as an array of u8 and large as a base64 String.

    extern crate serde_derive;
    
    extern crate serde;
    extern crate serde_bytes;
    
    #[derive(Serialize, Deserialize)]
    struct BytesStruct {
        small: Vec<u8>,
        #[serde(with = "serde_bytes")]
        large: Vec<u8>,
    }
    
    opened by fengalin 14
  • Update base64 requirement from 0.12 to 0.13

    Update base64 requirement from 0.12 to 0.13

    Updates the requirements on base64 to permit the latest version.

    Changelog

    Sourced from base64's changelog.

    0.13.0

    • Config methods are const
    • Added EncoderStringWriter to allow encoding directly to a String
    • EncoderWriter now owns its delegate writer rather than keeping a reference to it (though refs still work)
      • As a consequence, it is now possible to extract the delegate writer from an EncoderWriter via finish(), which returns Result<W> instead of Result<()>. If you were calling finish() explicitly, you will now need to use let _ = foo.finish() instead of just foo.finish() to avoid a warning about the unused value.
    • When decoding input that has both an invalid length and an invalid symbol as the last byte, InvalidByte will be emitted instead of InvalidLength to make the problem more obvious.

    0.12.2

    • Add BinHex alphabet

    0.12.1

    • Add Bcrypt alphabet

    0.12.0

    • A Read implementation (DecoderReader) to let users transparently decoded data from a b64 input source
    • IMAP's modified b64 alphabet
    • Relaxed type restrictions to just AsRef<[ut8]> for main encode*/decode* functions
    • A minor performance improvement in encoding

    0.11.0

    • Minimum rust version 1.34.0
    • no_std is now supported via the two new features alloc and std.

    0.10.1

    • Minimum rust version 1.27.2
    • Fix bug in streaming encoding (#90): if the underlying writer didn't write all the bytes given to it, the remaining bytes would not be retried later. See the docs on EncoderWriter::write.
    • Make it configurable whether or not to return an error when decoding detects excess trailing bits.

    0.10.0

    • Remove line wrapping. Line wrapping was never a great conceptual fit in this library, and other features (streaming encoding, etc) either couldn't support it or could support only special cases of it with a great increase in complexity. Line wrapping has been pulled out into a line-wrap crate, so it's still available if you need it.
      • Base64Display creation no longer uses a Result because it can't fail, which means its helper methods for common configs that unwrap() for you are no longer needed
    • Add a streaming encoder Write impl to transparently base64 as you write.
    • Remove the remaining unsafe code.
    • Remove whitespace stripping to simplify no_std support. No out of the box configs use it, and it's trivial to do yourself if needed: filter(|b| !b" \n\t\r\x0b\x0c".contains(b).
    • Detect invalid trailing symbols when decoding and return an error rather than silently ignoring them.

    0.9.3

    • Update safemem

    0.9.2

    • Derive Clone for DecodeError.
    Commits
    • b4fc913 v0.13.0
    • bba4c5d Merge pull request #145 from marshallpierce/mp/cleanup
    • 4296732 Add docs and other cleanup
    • 6bb3556 Merge pull request #144 from untitaker/invalid-bytes-not-length
    • 5b40e0c Merge pull request #142 from marshallpierce/mp/string-writer
    • 8b1ae22 Rename StrWrite to StrConsumer
    • 27ccb65 fix tests
    • d15cd38 Give better error messages when decoding data with trailing newlines
    • 5a56885 Introduce StrWriter to allow ESW to wrap both a String and a &mut String
    • 2dc0296 Merge pull request #143 from marshallpierce/mp/invalid-length-doc
    • Additional commits viewable in compare view

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language
    • @dependabot badge me will comment on this PR with code to add a "Dependabot enabled" badge to your readme

    Additionally, you can set the following in your Dependabot dashboard:

    • Update frequency (including time of day and day of week)
    • Pull request limits (per update run and/or open at any time)
    • Out-of-range updates (receive only lockfile updates, if desired)
    • Security updates (receive only security updates, if desired)
    dependency 
    opened by dependabot-preview[bot] 13
  • Improve error information for serde errors

    Improve error information for serde errors

    Followup to #393

    Adds explicit variants in ron::Error for serde errors from serde::de::Error (serde::ser::Error only has the Error::custom method).

    • [x] I've included my change in CHANGELOG.md
    opened by MomoLangenstein 12
  • pretty printing regression

    pretty printing regression

    I'm seeing a pretty printing regression in 0.6 from 0.5; looks to be in nested arrays and structs?

    E.g., seeing this in diffs now:

    +                ),            ],
    +        )),    ],
    

    I believe a newline is missing after the ),, since adding a newline after yields the expected pretty printed string:

                    ),
                ],
            )),
        ],
    
    bug 
    opened by m4b 12
  • Release 0.7.1 patch

    Release 0.7.1 patch

    We need #335 to land on crates. There may potentially be other things that could be included. @MomoLangenstein or @torkleyy - would you be interested in driving the patch release?

    enhancement 
    opened by kvark 11
  • Add compact arrays (#299) and pretty inline separators

    Add compact arrays (#299) and pretty inline separators

    This PR includes the implementation for compact arrays from #299 (stale and quite tricky to rebase), and a fix for #290 to make the pretty RON prettier. Specifically, this means that:

    • pretty tuples and arrays will now use a separator string after , when multiline is disabled
    • pretty structs and maps will now use a separator string after : and ,
    • this separator string is a single space by default
    • [x] I've included my change in CHANGELOG.md
    opened by MomoLangenstein 11
  • Need a new release

    Need a new release

    Specifically, unwrap_newtypes would be great to have for serialization as well as deserialization.

    This is especially relevant because serde recommends the "unwrapped" newtype representation, and ron is the odd one out in considering them semantically meaningful.

    help wanted 
    opened by CAD97 11
  • [v0.9] Breaking: Treat Some like any newtype variant

    [v0.9] Breaking: Treat Some like any newtype variant

    How should Some be treated in the presence of the unwrap_variant_newtypes extension? With that extension, NewtypeVariant(Some(a: 42, b: 24)) already worked, but Some(a: 42, b: 24) did not. In my opinion Some is just a newtype variant and should parse consistently here. @torkleyy what are your thoughts?

    • [x] I've included my change in CHANGELOG.md
    opened by MomoLangenstein 2
  • PrettyPrint struct names

    PrettyPrint struct names

    Is it possible to

    1. read a config
    2. prettyprint the ron::Value, while maintaining all struct names
    3. optionally convert the struct names to a tag when converting to serde_json::Value
    opened by qiujiangkun 1
  • Fixes #115 struct flattening

    Fixes #115 struct flattening

    Fixes #115 by allowing ron maps to be deserialised from structs. This is a hack. I am very unsure if this is something we want ron to support with serde's current model, or if we wanted to hold out for some extension to serde that would give Deserializer's more control about how to handle things like flatten and untagged enums etc.

    • [ ] I've included my change in CHANGELOG.md
    opened by MomoLangenstein 7
  • `Value` meta-issue

    `Value` meta-issue

    Just to start tracking all the Value related ones - I'll try to tackle them in 0.9:

    • [ ] #357
    • [ ] #328
    • [ ] #255
    • [ ] #217
    • [ ] #189
    • [ ] #140
    • [ ] #122
    • [ ] #115
    • [x] #407
    opened by MomoLangenstein 1
  • How should we handle MSRV?

    How should we handle MSRV?

    Oh, I see! The MSRV on 0.7 is still 1.36 anyways.

    How will we handle such breakage in the future?

    Originally posted by @MomoLangenstein in https://github.com/ron-rs/ron/issues/383#issuecomment-1159623984

    opened by torkleyy 1
Releases(v0.8.0)
  • v0.8.0(Aug 16, 2022)

    Changelog

    • Bump dependencies: bitflags to 1.3, indexmap to 1.9 (#399)
    • Add integer128 feature that guards i128 and u128 (#304, #351)
    • Fix issue #265 with better missing comma error (#353)
    • Fix issue #301 with better error messages (#354)
    • Fix issue #337 by removing decimal_floats PrettyConfig option and unconditional decimals in floats (#363)
    • Fix issue #203 with full de error positioning (#356)
    • Expand the ron::Error enum to distinguish serde errors like NoSuchEnumVariant and MissingStructField with error positioning (#394)
    • Bump MSRV to 1.56.0 (#396)

    Full changelog

    https://github.com/ron-rs/ron/compare/v0.7.1...v0.8.0

    Source code(tar.gz)
    Source code(zip)
  • v0.7.1(Jun 15, 2022)

    Changelog

    • Add struct_names option to PrettyConfig (#329)
    • Fix newtype variant unwrapping around enum, seq and map (#331)
    • Implement unwrap_newtypes extension during serialization (#333)
    • Implement unwrap_variant_newtypes extension during serialization (#336)
    • Add compact_arrays (#299) and separator options to PrettyConfig (#349)
    • Fix issue #338 value map roundtrip (#341)
    • Fix issue #289 enumerate_arrays comments (#344)
    • Report struct name in expected struct error (#342)
    • Add Options builder to configure the RON serde roundtrip (#343)
    • Fix issue #367 with eager implicit some (#368)
    • Fix issue #359 with DeserializeSeed support (#360)
    • Fix issue #370 with FromStr-equivalent float EBNF and Error::FloatUnderscore (#371)
    • Fix issue #374 extraneous .0 for small floats (#372)
    • Deprecate Serializer::new (#382)
    Source code(tar.gz)
    Source code(zip)
  • v0.7.0(Oct 22, 2021)

  • v0.6.6(Oct 22, 2021)

Owner
ron-rs
RON file format
ron-rs
Eon-rs - A reference parser for EON (Extensible Object Notation)

eon-rs eon-rs is a Rust library for parsing EON. Installation Add eon-rs = "1.0.0" to your Cargo.toml file. Usage use eon_rs; // Read EON from file l

Kurtis 4 Jun 3, 2022
Object Notation Programming Language?

You may have questions ONLang - Object Notation Language (jsON) VSCode extension - OnLang 1. God, what the f**** is this ONLang is an experimental, es

Artemy Egorov 7 Aug 29, 2022
Merge multiple Juniper object definitions into a single object type.

juniper-compose Merge multiple Juniper object definitions into a single object type. crates.io | docs | github Motivation You are building a GraphQL s

Kit Isaev 3 Aug 5, 2022
A game made for the Rusty Jam https://itch.io/jam/rusty-jam

Murder-User Dungeon Introduction Tony is a young man. Finally having its own apartment is a good thing! He will learn how to live by himself and how t

null 62 Dec 6, 2022
Rust experiments involving Haskell-esque do notation, state, failure and Nom parsers!

Introduction As a long time Haskell developer recently delving into Rust, something I've really missed is monads and do notation. One thing monadic do

Kerfuffle 23 Feb 28, 2022
a cheat-sheet for mathematical notation in Rust 🦀 code form

math-as-rust ?? Based on math-as-code This is a reference to ease developers into mathematical notation by showing comparisons with Rust code.

Eduardo Pereira 13 Jan 4, 2023
Easily create dynamic css using json notation

jss! This crate provides an easy way to write dynamic css using json notation. This gives you more convenient than you think. Considering using a dyna

Jovansonlee Cesar 7 May 14, 2022
A library for transcoding between bytes in Astro Notation Format and Native Rust data types.

Rust Astro Notation A library for transcoding between hexadecimal strings in Astro Notation Format and Native Rust data types. Usage In your Cargo.tom

Stelar Software 1 Feb 4, 2022
Friendly symbol notation.

symmie Friendly symbol notation. The goal of this project is to provide a systematic notation for technical symbols and emoji. The notation consist of

Typst 6 Dec 28, 2022
PICNIC Is Config Notation Interpreter/Converter

PICNIC Is Config Notation Interpreter/Converter ?? PICNIC PICNIC's name is powered by AI, which immediately makes it worth your time: Human: Please co

Fabricio Demattê 4 Jul 13, 2023
Object Pool LockFree in Rust

Lock Free Object Pool A thread-safe object pool collection with automatic return. Some implementations are lockfree : LinearObjectPool SpinLockObjectP

Vaillant Etienne 30 Sep 7, 2022
C++ `std::unique_ptr` that represents each object as an NFT on the Ethereum blockchain

C++ `std::unique_ptr` that represents each object as an NFT on the Ethereum blockchain

null 1.9k Dec 28, 2022
Educational Rust implemenation of Auction Sniper from Growing Object-Oriented Software, Guided By Tests

Auction Sniper Educational Rust not-OOP implemenation of Auction Sniper from "Growing Object-Oriented Software, Guided By Tests" book More about it in

Dawid Ciężarkiewicz 23 Nov 11, 2022
It is a backup tool that creates backups and stores them on an object storage

Hold My Backup It is a backup tool that creates backups and stores them on an object storage. By default it uses minio but you can use AWS: S3 as well

Taylan Dogan 13 Feb 17, 2022
An object-relational in-memory cache, supports queries with an SQL-like query language.

qlcache An object-relational in-memory cache, supports queries with an SQL-like query language. Warning This is a rather low-level library, and only p

null 3 Nov 14, 2021
Garage is a lightweight S3-compatible distributed object store

Garage [ Website and documentation | Binary releases | Git repository | Matrix channel ] Garage is a lightweight S3-compatible distributed object stor

Deuxfleurs 156 Dec 30, 2022
Merge together and efficiently time-sort compressed .pcap files stored in AWS S3 object storage (or locally) to stdout for pipelined processing.

Merge together and efficiently time-sort compressed .pcap files stored in AWS S3 object storage (or locally) to stdout for pipelined processing. High performance and parallel implementation for > 10 Gbps playback throughput with large numbers of files (~4k).

null 4 Aug 19, 2022
CBOR: Concise Binary Object Representation

CBOR 0x(4+4)9 0x49 “The Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of extremely small cod

quininer 37 Dec 27, 2022
My solutions for the 2021 edition of the Advent of Code, using Rust and SOM (Simple Object Machine)

Advent of Code 2021 These are my solutions for the 2021 edition of the Advent of Code. The solutions are all implemented using both Rust and SOM (Simp

Nicolas Polomack 1 Dec 23, 2021
Qoo - Query Object Oriented. Pronunciation is Kuu.

qoo Query Object Oriented. Pronunciation is Kuu. demo use qoo::base::*; use qoo::select::*; use qoo::insert::*; use qoo::update::*; use qoo::delete::*

Ochi Daiki 2 May 13, 2022