JSON implementation in Rust

Overview

json-rust

Parse and serialize JSON with ease.

Changelog - Complete Documentation - Cargo - Repository

Why?

JSON is a very loose format where anything goes - arrays can hold mixed types, object keys can change types between API calls or not include some keys under some conditions. Mapping that to idiomatic Rust structs introduces friction.

This crate intends to avoid that friction.

let parsed = json::parse(r#"

{
    "code": 200,
    "success": true,
    "payload": {
        "features": [
            "awesome",
            "easyAPI",
            "lowLearningCurve"
        ]
    }
}

"#).unwrap();

let instantiated = object!{
    // quotes on keys are optional
    "code": 200,
    success: true,
    payload: {
        features: [
            "awesome",
            "easyAPI",
            "lowLearningCurve"
        ]
    }
};

assert_eq!(parsed, instantiated);

First class citizen

Using macros and indexing, it's easy to work with the data.

let mut data = object!{
    foo: false,
    bar: null,
    answer: 42,
    list: [null, "world", true]
};

// Partial equality is implemented for most raw types:
assert!(data["foo"] == false);

// And it's type aware, `null` and `false` are different values:
assert!(data["bar"] != false);

// But you can use any Rust number types:
assert!(data["answer"] == 42);
assert!(data["answer"] == 42.0);
assert!(data["answer"] == 42isize);

// Access nested structures, arrays and objects:
assert!(data["list"][0].is_null());
assert!(data["list"][1] == "world");
assert!(data["list"][2] == true);

// Error resilient - accessing properties that don't exist yield null:
assert!(data["this"]["does"]["not"]["exist"].is_null());

// Mutate by assigning:
data["list"][0] = "Hello".into();

// Use the `dump` method to serialize the data:
assert_eq!(data.dump(), r#"{"foo":false,"bar":null,"answer":42,"list":["Hello","world",true]}"#);

// Or pretty print it out:
println!("{:#}", data);

Installation

Just add it to your Cargo.toml file:

[dependencies]
json = "*"

Then import it in your main.rs / lib.rs file:

#[macro_use]
extern crate json;

Performance and Conformance

There used to be a statement here saying that performance is not the main goal of this crate. It is definitely one of them now.

While this crate doesn't provide a way to parse JSON to native Rust structs, it does a lot to optimize its performance for DOM parsing, stringifying and manipulation. It does very well in benchmarks, in some cases it can even outperform parsing to structs.

This crate implements the standard according to the RFC 7159 and ECMA-404 documents. For the best interoperability numbers are treated stored as 64bit precision mantissa with 16 bit decimal exponent for floating point representation.

License

This crate is distributed under the terms of both the MIT license and the Apache License (Version 2.0). Choose whichever one works best for you.

See LICENSE-APACHE and LICENSE-MIT for details.

Comments
  • Performance comparison with other existing libraries in README.md

    Performance comparison with other existing libraries in README.md

    This would be interesting for many developers and a strong argument to use this library, respectively rust instead of another language.

    In the comparison the version number of the respective lib should be indicated. Especially a comparison with serd is interesting. https://github.com/serde-rs/serde

    enhancement documentation 
    opened by StefanoD 27
  • It's possible to remove the `iterators` module entirely.

    It's possible to remove the `iterators` module entirely.

    We can define type aliases for Members , MembersMut, Entries, EntriesMut, for example:

    pub type Members<'a> = slice::Iter<'a, JsonValue>;
    

    And change methods to return Option:

    pub fn members(&self) -> Option<Members>
    

    It's a little inconvenient on a call site, but that way we can eliminate one level of indirection. @maciejhirsz, If you're ok with this I can implement it.

    enhancement discussion 
    opened by zummenix 22
  • Parsed json data is not in the same order as the original.

    Parsed json data is not in the same order as the original.

    Thanks for this crate! I'm currently writing a code generator, where you can define the API using JSON. I noticed that if a list of elements is used, the resulting parsed output is not in the same order as defined in the original JSON data, which is a bit of a problem. Example:

    What I pass to JSON parser:

    {
      "struct": {
      "var": { "type": "int", "name": "x" },
      "func": [ { "type": "int", "name": "return_int" } ]
      }
    }
    

    What I get after parsing and printing the parsed data to screen:

    {"struct":{"func":[{"name":"return_int","type":"int"}],"var":{"name":"x","type":"int"}}}
    

    Is there a way to get the output exactly in the same order as I defined? So far I'm iterating over members() and entries() and I can't see any other way to do it properly.

    Thanks!

    enhancement 
    opened by kondrak 12
  • map_* methods

    map_* methods

    Instead of:

    let data = object!{ foo => 10 };
    
    let Some(num) = data["foo"].as_f64() {
        data["foo"] = (num + 1).into();
    }
    
    assert_eq(data.dump(), r#"{"foo":11}"#);
    

    Do:

    let data = object!{ foo => 10 };
    
    data["foo"].map_f64(|num| num + 1);
    
    assert_eq(data.dump(), r#"{"foo":11}"#);
    

    👍 or 👎 ?

    discussion 
    opened by maciejhirsz 11
  • Higher precision decimals

    Higher precision decimals

    So I'm going back and forth on the idea of using a custom number type.

    While it's nice to be able to parse higher precision than f64, it's also pretty useless unless there is a way to use that somehow. A solution for that could be methods like:

    • as_fixed_point_u64(u16) -> Option<u64>
    • as_fixed_point_i64(u16) -> Option<i64>

    This way a number such as 12.3456 can be obtained as an integer 123456 when called with fixed point argument 4. A way to construct such numbers would be needed as well (macro?)

    Pros:

    • Much faster serializing (canada.json will be a breeze).
    • Parsing higher precision might be actually useful.

    Cons:

    • Obscuring the API, though this is already done with Object and Short types.
    • Converting floats to the decimal representation is costly. I've already done an experimental alteration of the dtoa crate to produce decimal mantissa and exponent instead of writing to string with the grisu2 algorithm. Pefromance of that is quite okay.

    Open questions:

    • Is 64 bit mantissa for precision enough?
    • Do we enable maths on the Number type and/or JsonValue?
    • Can we use feature flags to convert numer types from other crates, in particular num crate?
    enhancement 
    opened by maciejhirsz 9
  • `stringify` takes ownership instead of a reference

    `stringify` takes ownership instead of a reference

    Is there a reason it takes the JsonValue by value instead of by reference?

    I have a Cache that contains a JsonValue which is updated in place, and every once in a while it saves it to disk as JSON, so currently I have to clone the object which sounds like an artificial requirement.

    Other than the obvious loss of the nice json::stringify(2) and friends, I think it would be a win performance wise (at least for my case :panda_face:)

    opened by meh 8
  • Methods to check truthiness.

    Methods to check truthiness.

    I'm finding myself wanting to check for truthyness instead of specific values and maybe it could be nice to have an is_truthy and is_falsy method in JsonValue?

    It's just to avoid the !json[key].is_null() && json[key].as_bool().unwrap_or(false) boilerplate everywhere.

    Or maybe there's already a way to do it and I'm not seeing it? Great library by the way.

    enhancement discussion documentation 
    opened by meh 8
  • Deprecation warning/error with json-rust 0.9.0

    Deprecation warning/error with json-rust 0.9.0

    Thanks for pushing the requests so quickly! :) However, when trying to compile a new cargo project with json 0.9.0, 2 deprecation warnings are being generated:

    -*- mode: compilation; default-directory: "d:/hello_world/" -*-
    Compilation started at Sat Jul 16 20:01:46
    
    make -k 
    RUST_BACKTRACE=1 cargo run
       Compiling bitflags v0.7.0
       Compiling ftoa v0.1.1
       Compiling itoa v0.1.1
       Compiling xml-rs v0.3.4
       Compiling json v0.9.0
    C:\Users\(...)\json-0.9.0\src\lib.rs:238:1: 238:63 error: `#[deprecated]` attribute is unstable (see issue #29935)
    C:\Users\(...)\json-0.9.0\src\lib.rs:238 #[deprecated(since="0.9.0", note="use `json::Error` instead")]
                                                                                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    C:\Users\(...)\json-0.9.0\src\lib.rs:241:1: 241:64 error: `#[deprecated]` attribute is unstable (see issue #29935)
    C:\Users\(...)\json-0.9.0\src\lib.rs:241 #[deprecated(since="0.9.0", note="use `json::Result` instead")]
                                                                                                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    error: aborting due to 2 previous errors
    Build failed, waiting for other jobs to finish...
    Could not compile `json`.
    

    Since it's set to treat deprecations as errors, maybe just remove them altogether?

    opened by kondrak 6
  • cannot borrow variables in object!

    cannot borrow variables in object!

    I'm trying to create my data object and serialize it for sending through my network. but I'm not able to borrow "src" in my object. I need the src to use it in the send_to() method.

    is that a bug or the structure should be this way only?

    let mut data = object!{
        "HEADER" => "RES:REGISTER",
        "SOURCE" => &src,
        "BODY" => object!{
            "UUID" => reg_serial
        }
    };
    
    // even i've tried this
    //data["SOURCE"] = &src.into(); 
    
    let serialised_data = json::stringify(data);
    socket.send_to(&serialised_data.into_bytes(), &src).expect("cannot send");
    

    the error is

    error[E0277]: the trait bound `json::value::JsonValue: std::convert::From<&std::string::String>` is not satisfied
       --> src/main.rs:95:20
        |
    95  |       let mut data = object!{
        |  ____________________^
    96  | |         "HEADER" => "RES:REGISTER",
    97  | |         "SOURCE" => &src,
    98  | |         "BODY" => object!{
    99  | |             "UUID" => reg_serial
    100 | |         }
    101 | |     };
        | |_____^ the trait `std::convert::From<&std::string::String>` is not implemented for `json::value::JsonValue`
        |
        = help: the following implementations were found:
                  <json::value::JsonValue as std::convert::From<bool>>
                  <json::value::JsonValue as std::convert::From<i8>>
                  <json::value::JsonValue as std::convert::From<isize>>
                  <json::value::JsonValue as std::convert::From<usize>>
                and 17 others
        = note: required because of the requirements on the impl of `std::convert::Into<json::value::JsonValue>` for `&std::string::String`
        = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)
    
    error: aborting due to previous error
    
    opened by ardawan 5
  • SIGSEGV

    SIGSEGV

    Need to find a way to reproduce, as it apparently happens on stable Rust: https://github.com/rust-lang/rust/issues/38687

    edit: running cargo test --test value reproduces the issue

    bug 
    opened by maciejhirsz 5
  • Consider adding a take_string method to JsonValue.

    Consider adding a take_string method to JsonValue.

    When parsing JSON data, it can be useful to take certain string values out and place them into variables/structs which will outlive the original data.

    It would be nice to have a fn take_string() -> Option<String> method which would return None if the value wasn't a string and return the inner string, replacing it with JsonValue::Null.

    Other variants don't need/can't have this as they are Copy.

    enhancement 
    opened by Mark-Simulacrum 5
  • Update lifetimes of `read_complex_string`

    Update lifetimes of `read_complex_string`

    The lifetimes of read_complex_string in parser.py are weird. It returns a slice, but the lifetime of the slice is not tied to either the lifetime of self or the lifetime of the struct.

    pub fn read_complex_string<'b>(&mut self, start: usize) -> Result<&'b str>
    

    This could cause potential memory errors. Eg :

    let sl2;
    {
      let a: String = String::from("bftb\"ftbft");
      let sl: &str = &a[0..5];
      
      let mut parser = Parser::new(sl);
      parser.bump();
      sl2 = parser.read_complex_string(0);
    }
    println!("{:?}", sl2); // Will print garbage because the String has been dropped
    

    This signature makes more sense and passes all tests.

    pub fn read_complex_string(&mut self, start: usize) -> Result<&'_ str>
    
    opened by vnrst 0
  • Add Natvis definitions and tests for `json` types

    Add Natvis definitions and tests for `json` types

    This change adds Natvis visualizations for types in the json crate to help improve the debugging experience on Windows.

    Natvis is a framework that can be used to specify how types should be viewed under a supported debugger, such as the Windows debugger (WinDbg) and the Visual Studio debugger.

    The Rust compiler does have Natvis support for some types, but this is limited to some of the core libraries and not supported for external crates.

    https://github.com/rust-lang/rfcs/pull/3191 proposes adding support for embedding debugging visualizations such as Natvis in a Rust crate. This RFC has been approved, merged and implemented.

    This PR adds:

    • Natvis visualizations for json types.
    • Tests for testing visualizers embedded in the json crate.
    • A new debugger_visualizer feature for the json crate to enable the unstable debugger_visualizer Rust feature.
    opened by ridwanabdillahi 0
  • Is this project abandoned?

    Is this project abandoned?

    I have been waiting for the major update stated in #181 :

    If your strings are short they will be inlined on stack and use JsonValue::Short instead of JsonValue::String. That said, the next big release of the crate will remove the Short variant, and use Cow for strings instead.

    So just wondering.

    opened by your-diary 3
  •  How is the library memory consumption compared to serde_json?

    How is the library memory consumption compared to serde_json?

    Looking around it seems like serde_json memory overhead is significant I wonder how good is json-rust compared to it. Also it seems like there are other libraries that are trying to improve it: https://github.com/Diggsey/ijson

    opened by gkorland 0
  • Can not be indexed by u32

    Can not be indexed by u32

    Error:

    error[E0277]: the type `JsonValue` cannot be indexed by `u32`
      --> src/lib.rs:65:12
       |
    65 |     while !parsed["functions"][c].is_null() {
       |            ^^^^^^^^^^^^^^^^^^^^^^ `JsonValue` cannot be indexed by `u32`
       |
       = help: the trait `Index<u32>` is not implemented for `JsonValue`
    

    I'm guessing a manually typed in number automatically converts itself to a compatible type for indexing?

    opened by amyipdev 1
Releases(v0.12.4)
  • v0.12.4(Mar 18, 2020)

  • v0.12.3(Mar 17, 2020)

    • Improved macro syntax:
      • Object "key" => value pair can be now written as either "key": value or key: value without quotes, as long as key is an identifier.
      • If you want to use the value of the a variable as a key in the new notation, use [foo]: value.
      • When nesting objects or arrays, it's no longer necessary to use invoke array! or object! from within another macro.
      • null is a keyword inside of either macro.
      • This is a backwards compatible change, although mixing notations within a single macro invocation is not permitted.

    Example

    Instead of:

    let obj = object! {
        "foo" => array![1, 2, json::Null],
        "bar" => 42
    };
    

    You can now write:

    let obj = object! {
        foo: [1, 2, null],
        bar: 42
    };
    
    Source code(tar.gz)
    Source code(zip)
  • v0.12.2(Mar 11, 2020)

  • v0.12.1(Jan 14, 2020)

  • v0.12.0(Sep 6, 2019)

    • Updated to edition 2018.
    • Simplified reading escaped unicode in strings a bit.
    • Provided From<&[T]> implementation for JsonValue where T: Into<JsonValue> (closes #160).
    • object! and array! macros will no longer re-allocate (closes #159).
    • object! and array! macros can be now used without being imported into local scope (by using json::object! or json::array!, thanks @matthias-t).
    • BREAKING HashMap and BTreeMap conversions are now more generic, working for any pair of K key and V value where K: AsRef<str> and V: Into<JsonValue>. This means that type inference won't always work in your favor, but should be much more flexible.
    • You can now .collect() an interator of (K, V) (with bounds same as point above) into an Object.
    Source code(tar.gz)
    Source code(zip)
  • v0.11.13(Jan 17, 2018)

  • v0.11.12(Nov 10, 2017)

  • v0.11.11(Nov 10, 2017)

    • Fixes an issue when parsing objects with non-unique names (#136).
    • Fixed a warning on #[must_use] (#119).
    • Deprecated Object::override_last, it was only public out of necessity before pub(crate) was introduced.
    Source code(tar.gz)
    Source code(zip)
  • v0.11.10(Oct 7, 2017)

    Thanks to @Yoric for contributions:

    • Implemented dump and pretty for Object, see #131
    • Two string JsonValues are now equal even if one is a Short while the other is a String variant, see #126
    • The object! macro now handles trailing commas, see #125
    Source code(tar.gz)
    Source code(zip)
  • v0.11.9(Jul 28, 2017)

  • v0.11.8(Jul 3, 2017)

    • Fixed an issue that lead to a panic when trying to print Number types with negative exponent but with large base, where putting the period after first digit would force the scientific e notation to flip sign to positive (issue #108, thank you @lpbak)
    Source code(tar.gz)
    Source code(zip)
  • v0.11.7(Jun 26, 2017)

  • v0.11.6(Mar 15, 2017)

  • v0.11.5(Jan 21, 2017)

    • Object struct now implements Index and IndexMut on it's own. Thanks to @hobofan for #105.
    • Fixed a rare SIGSEGV that could occur during serialization or iteration over objects due to invalid lifetimes being applied on unsafe code. Reduced the amount of unsafe code around to increase maintainability of the project, more to come.
    Source code(tar.gz)
    Source code(zip)
  • v0.11.4(Jan 2, 2017)

    • To allow for custom implementators of From<T> for JsonValue to benefit from automatic conversions, the trait implementations are now using generics instead of macros internally (see #101).
    Source code(tar.gz)
    Source code(zip)
  • v0.11.3(Nov 30, 2016)

  • v0.11.2(Nov 25, 2016)

  • v0.11.1(Nov 23, 2016)

  • v0.11.0(Oct 28, 2016)

    • Breaking change: Error enum now has a new variant: ExceededDepthLimit.
    • Stack overflow issues on deeply nested structures should now be fixed (#93).
      • Parser has been reworked to avoid recursion and instead run in a loop with a custom, heap allocated, stack for nested objects and arrays.
      • As an additional sanity check parsing will now stop after hitting 512 nested objects or arrays and return Error::ExceededDepthLimit.
    • Fixed an issue that caused a panic when unwinding the parser on a single unicode character.
    Source code(tar.gz)
    Source code(zip)
  • v0.10.3(Oct 26, 2016)

    • Fixed integer overflow causing a panic when parsing very long exponents.
    • Parser now returns an error on malformatted numbers which are missing a digit after a period (example: [1.]).
    Source code(tar.gz)
    Source code(zip)
  • v0.10.2(Aug 11, 2016)

    • Deprecated JsonValue::to_writer as it would panic on writing errors.
    • Implemented JsonValue::write and JsonValue::write_pretty, both returning std::io::Result.
    • Implemented JsonValue::has_key.
    Source code(tar.gz)
    Source code(zip)
  • v0.10.1(Aug 1, 2016)

  • v0.10.0(Jul 22, 2016)

    Breaking changes

    • JsonValue::Number now stores a new json::number::Number type instead of f64.
    • Error::UndefinedField was removed since it wasn't used anywhere.

    The new Number

    This release introduces a new Number type. The RFC 7159 talks about the interoperability issues between JSON implementations and allows them to limit the precision range. The recommended minimum is double precision IEEE 754 binary floating points as the base number type, as support for it is widely available.

    The new Number type is composed of a 64 bit unsigned mantissa, 16 bit signed decimal exponent and a marker for a sign or NaN-ness of the number. It's thus capable of representing the full range of u64 and i64 integers, as well as the full range of f64, including negative zero. Infinite values were omitted as they cannot be represented in JSON.

    While Rust lacks a native decimal floating point type, json-rust provides fast conversion from any Rust number type to the new Number, and by extension to JsonValue. All methods for obtaining numbers as specific types work just as well as they did before, and the as_u64 / as_i64 methods can now produce precise values.

    Fixed point arithmetic

    Two new methods have been added to the JsonValue type:

    • as_fixed_point_u64
    • as_fixed_point_i64

    Those make it easy to work with numeric values where a fixed amount of fractional digits is expected. For example: a price such as 4.99 can be obtained as an integer of cents 499 using .as_fixed_point_u64(2), where 2 is the number of digits in the fraction. This conversion is very cheap and (since it works on decimal exponents) free of any rounding errors that plague binary floating points.

    Upgrading

    If you have been using JsonValue::Number directly to construct numeric values, the easiest way to upgrade to 0.10 is to replace expressions such as JsonValue::Number(10) with JsonValue::from(10). The From and Into traits implemented for JsonValue should always keep you covered with the best performance.

    Performance

    Since decimal floats are represented in a form that closely matches the e notation in JSON strings, printing them out to strings is very fast and always accurate. In benchmarks testing stringifying of large amount of floating point numbers, json-rust is now nearly 3 times faster than the previous release.

    This performance gain is, however, a tradeoff. If you create numbers by conversion from f64 (for example: JsonValue::from(3.14)) you will pay part of the cost that would previously be attached to stringifying head on. The algorithm used for that is the same as we've used before for writing f64 to strings, and the combined cost of conversion to decimal float + printing is virtually identical to that of printing a f64 itself. Converting from decimal floating point to f64 is still very cheap, the cost of reading parsed numbers hasn't changed in practice.

    In future releases I plan to work on procedural macros, so that writing 3.14 inside array! or object! will compile to a Number construct directly, without converting from f64 on runtime, thus mostly eliminating the cost of the tradeoff.

    Source code(tar.gz)
    Source code(zip)
  • v0.9.1(Jul 18, 2016)

    • Tweaked some details about the new Object type and improved number parsing in general. Over all the parsing time dropped by another ~10%.
    • Added a lot of new comments to the code, should make contributors' life easier.
    Source code(tar.gz)
    Source code(zip)
  • v0.9.0(Jul 16, 2016)

    Breaking changes

    • JsonValue got a lot of work put into it:
      • The Object variant has changed from storing BTreeMap<String, JsonValue> to storing a new json::object::Object type.
      • A new Short variant has been added, storing the new json::short::Short type. Those are short (up to 30 bytes) strings that can be allocated on the stack at no additional cost to memory on 64bit architecture.
    • JsonResult and JsonError have been renamed to just Result and Error respectively (see issue #38). Aliases have been provided to keep things backwards compatible, but the old names are considered deprecated and you are advised to migrate to the new ones.
    • On top of the name change, the Error enum no longer has the ArrayIndexOutOfBounds variant. It hasn't been used for a while.
    • Members, MembersMut, Entries and EntriesMut are no longer enums and cannot be pattern-matched (read below about iterator improvements).
    • The Entries and EntriesMut iterators now yield &str instead of &String as the first member of the entry tuple. Depending on your implementation this might or might not be a breaking change (as &String would automatically deref to &str anyway).

    Shorts

    The new Short variant should be completely transparent to you, and shouldn't in any way affect how you use the library. They are both considered strings as far as all methods are concerned. When creating new values, the right type is chosen for you:

    // create a JsonValue::Short
    data["foo"] = "bar".into(); 
    
    // create a JsonValue::String (from Neal Stephenson's "Anathem")
    data["quote"] = "And it happened all the time that the compromise \
                     between two perfectly rational alternatives was something \
                     that made no sense at all.".into();
    
    // Both are considered strings, and all string methods work on both
    assert!(data["foo"].is_string());
    assert!(data["quote"].is_string());
    

    Object keys are now stored in insertion order

    The new implementation of the Object type acts as a Binary Search Tree, with the deviation from a standard implementation of BST in that the nodes aren't separately allocated on the heap, but rather are collectively allocated on an internal vector, reducing allocations and preserving insertion order. This means that all objects are now stringified in the same order they were parsed or instantiated (see issue #68).

    Performance improvements

    • The new Short type, as well as the new Object type, both exploit the fact that short strings don't have to be separately allocated on the heap. JSON is, after all, an Object Notation where all keys and plenty of data are nothing but strings. Avoiding the unnecessary heap allocations has, in some cases, cut parsing times by half compared to the previous release!
    • Iterators are now much faster too. Previously calling .members() or .entries() would return an enum, which would in turn use pattern matching on each iteration. We are much smarter now. Trying to get an iterator from a wrong type will yield a true empty iterator - those are very cheap to create as they require no heap allocation. In fact, the Members and MembersMut iterators are now just type aliases for std::slice::Iter<'a, JsonValue> and std::slice::IterMut<'a, JsonValue>. Thanks to @zummenix for the work done on this (see issue #67).
    • A very minor thing, but moving away from BTreeMap for object storage, means the JsonValue enum on 64bit architecture now dropped from being 40 bytes to 32 bytes long.

    Apache 2.0 License

    In good Rust fashion, Apache 2.0 license has been added as an option.

    Source code(tar.gz)
    Source code(zip)
  • v0.8.8(Jul 10, 2016)

    This is a patch release that adds a take_string method to JsonValue:


    Checks that self is a string, returns an owned Rust String, leaving Null in it's place.

    This is the cheapest way to obtain an owned String from JSON, as no extra heap allocation is performend.

    let mut data = array!["Hello", "World"];
    
    let owned = data[0].take_string().expect("Should be a string");
    
    assert_eq!(owned, "Hello");
    assert!(data[0].is_null());
    
    Source code(tar.gz)
    Source code(zip)
  • v0.8.7(Jul 7, 2016)

    This is a patch release that includes two new utilities:

    • @imp implemented DoubleEndedIterator for all iterator types, so iterating over array entries or object members is now more powerful, and more closely maps to what is possible with regular vectors and maps.

    • You can now .take() owned values out of a structure leaving a null in place, useful for avoiding cloning all over the place:

      let mut data = array!["Foo", 42];
      
      let first = data[0].take();
      let second = data[1].take();
      
      assert!(first == "Foo");
      assert!(second == 42);
      
      assert!(data[0].is_null());
      assert!(data[1].is_null());
      
    Source code(tar.gz)
    Source code(zip)
  • v0.8.6(Jul 6, 2016)

    This is a patch release that fixes some more obscure standard conformance issues. Decimal number parsing has been improved and should be now both faster and produce more precise results (as long as they are within the range of f64 which json-rust uses internally for all numbers).

    Source code(tar.gz)
    Source code(zip)
  • v0.8.5(Jul 4, 2016)

    This issue attempts to fix few issues with varying severity, as well as be more spec conforming - whitespace in JSON source will no longer be accepted, and control characters will be properly encoded as \uXXXX where X is a hexadecimal digit.

    There are also minor improvements to serialization performance.

    Source code(tar.gz)
    Source code(zip)
  • v0.8.4(Jul 1, 2016)

    Fixing a bug that occurred in 0.8.2. Good thing about being a niche crate: managed to yank the broken version from cargo before it got downloaded.

    Source code(tar.gz)
    Source code(zip)
Owner
Maciej Hirsz
Core Interloper @ Parity Technologies
Maciej Hirsz
JSON parser which picks up values directly without performing tokenization in Rust

Pikkr JSON parser which picks up values directly without performing tokenization in Rust Abstract Pikkr is a JSON parser which picks up values directl

Pikkr 615 Dec 29, 2022
Strongly typed JSON library for Rust

Serde JSON   Serde is a framework for serializing and deserializing Rust data structures efficiently and generically. [dependencies] serde_json = "1.0

null 3.6k Jan 5, 2023
Rust port of gjson,get JSON value by dotpath syntax

A-JSON Read JSON values quickly - Rust JSON Parser change name to AJSON, see issue Inspiration comes from gjson in golang Installation Add it to your

Chen Jiaju 90 Dec 6, 2022
A rust script to convert a better bibtex json file from Zotero into nice organised notes in Obsidian

Zotero to Obsidian script This is a script that takes a better bibtex JSON file exported by Zotero and generates an organised collection of reference

Sashin Exists 3 Oct 9, 2022
CLI tool to convert HOCON into valid JSON or YAML written in Rust.

{hocon:vert} CLI Tool to convert HOCON into valid JSON or YAML. Under normal circumstances this is mostly not needed because hocon configs are parsed

Mathias Oertel 23 Jan 6, 2023
Typify - Compile JSON Schema documents into Rust types.

Typify Compile JSON Schema documents into Rust types. This can be used ... via the macro import_types!("types.json") to generate Rust types directly i

Oxide Computer Company 73 Dec 27, 2022
A easy and declarative way to test JSON input in Rust.

assert_json A easy and declarative way to test JSON input in Rust. assert_json is a Rust macro heavily inspired by serde json macro. Instead of creati

Charles Vandevoorde 8 Dec 5, 2022
A small rust database that uses json in memory.

Tiny Query Database (TQDB) TQDB is a small library for creating a query-able database that is encoded with json. The library is well tested (~96.30% c

Kace Cottam 2 Jan 4, 2022
A JSON Query Language CLI tool built with Rust 🦀

JQL A JSON Query Language CLI tool built with Rust ?? ?? Core philosophy ?? Stay lightweight ?? Keep its features as simple as possible ?? Avoid redun

Davy Duperron 872 Jan 1, 2023
rurl is like curl but with a json configuration file per request

rurl rurl is a curl-like cli tool made in rust, the difference is that it takes its params from a json file so you can have all different requests sav

Bruno Ribeiro da Silva 6 Sep 10, 2022
A tool for outputs semantic difference of json

jsondiff A tool for outputs semantic difference of json. "semantic" means: sort object key before comparison sort array before comparison (optional, b

niboshi 3 Sep 22, 2021
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
Decode Metaplex mint account metadata into a JSON file.

Simple Metaplex Decoder (WIP) Install From Source Install Rust. curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh Clone the source: git c

Samuel Vanderwaal 8 Aug 25, 2022
A fast and simple command-line tool for common operations over JSON-lines files

rjp: Rapid JSON-lines processor A fast and simple command-line tool for common operations over JSON-lines files, such as: converting to and from text

Ales Tamchyna 3 Jul 8, 2022
A node package based on jsonschema-rs for performing JSON schema validation

A node package based on jsonschema-rs for performing JSON schema validation.

dxd 49 Dec 18, 2022
Tools for working with Twitter JSON data

Twitter stream user info extractor This project lets you parse JSON data from the Twitter API or other sources to extract some basic user information,

Travis Brown 4 Apr 21, 2022
A fast way to minify JSON

COMPACTO (work in progress) A fast way to minify JSON. Usage/Examples # Compress # Input example (~0.11 KB) # { # "id": "123", # "name": "Edua

Eduardo Stuart 4 Feb 27, 2022
JSON Schema validation library

A JSON Schema validator implementation. It compiles schema into a validation tree to have validation as fast as possible.

Dmitry Dygalo 308 Dec 30, 2022
Jq - Command-line JSON processor

jq jq is a lightweight and flexible command-line JSON processor. , Unix: , Windows: If you want to learn to use jq, read the documentation at https://

Stephen Dolan 23.9k Jan 4, 2023