An auxiliary library for the serde crate.

Overview

serde-aux

Crates badge CI Documentation MIT licensed

An auxiliary library for the serde crate.

Contains some useful helper stuff. See docs for more info.

The library is free for any contributions. The goal of this crate is to improve the user experience of the serde crate.

Rust version

The minimal rust version the library supports:

  • Up to version 3.0.0 (excluding) - rustc 1.36.
  • Since 3.0.0 - rustc 1.56.

License

This project is licensed under the MIT license.

Comments
  • Feature Request: Get the field names of a struct

    Feature Request: Get the field names of a struct

    Hi

    Would a function implemented in this issue, be useful in this crate? https://github.com/serde-rs/serde/issues/1110

    fn main() {
        // prints ["error", "description"]
        println!("{:?}", struct_fields::<AuthError>());
    }
    

    A function like this would eliminate a lot of boiler plate code in my app. I copied and pasted the implementation into my application and it works but I think it would be useful as apart of this library. The original issue was closed.

    Note: link has implementation for enum and struct

    opened by ta32 9
  • `StringOrVecToVec` with trailing separator.

    `StringOrVecToVec` with trailing separator.

    I have to parse a string of hex-encoded, space-separated bytes in a string but the source API includes a trailing space: "a1 b2 c3 d4 ".

    If using a parser to turn the items into something other than a string type, such as an int, the parsing will fail due to the empty item.

    Here is a test which demonstrates the problem:

    #[test]
    fn test_bytes_from_string() {
        fn bytes_from_string<'de, D>(deserializer: D) -> std::result::Result<Vec<u8>, D::Error>
        where
            D: serde::Deserializer<'de>,
        {
            StringOrVecToVec::new(' ', |s| {
                println!("{:?}", &s);
                u8::from_str_radix(s, 16)
            })
            .into_deserializer()(deserializer)
        }
    
        #[derive(serde::Deserialize, Debug)]
        struct MyStruct {
            #[serde(deserialize_with = "bytes_from_string")]
            list: Vec<u8>,
        }
    
        // Works
        let s = r#" { "list": "a1 b2 c3 d4" } "#;
        let a: MyStruct = serde_json::from_str(s).unwrap();
        assert_eq!(&a.list, &[0xa1, 0xb2, 0xc3, 0xd4]);
    
        // Fails:
        //   thread 'test_bytes_from_string' panicked at 'called `Result::unwrap()` on an `Err` value: Error("cannot parse integer from empty string", line: 1, column: 27)'
        let s = r#" { "list": "a1 b2 c3 d4 " } "#;
        let a: MyStruct = serde_json::from_str(s).unwrap();
    }
    

    Is there a way to resolve this or is this a bug with trailing separators?

    opened by bjeanes 7
  • RUSTSEC-2020-0071 and 'chrono' dependency

    RUSTSEC-2020-0071 and 'chrono' dependency

    Hello,

    Apparently the 'chrono' crate still includes its 'oldtime' feature as a default, which depends on an old version of the 'time' crate (v0.1.43) that has a vulnerability in it. https://rustsec.org/advisories/RUSTSEC-2020-0071.html

    For my own projects, I disable chrono's default features, then manually include all of the defaults except for 'oldtime', which is what the readme on chrono's repo recommends.

    However, pulling in serde_aux seems to bring in chrono with the 'default' features selected, including 'oldtime'.

    Any chance you could remove the 'oldtime' feature from your dependency on chrono to avoid this CVE in downstream projects?

    opened by damccull 7
  • deserialize_default_from_empty_object with null value

    deserialize_default_from_empty_object with null value

    With the following code, I get an error when the incoming json has a null value for a field.

    extern crate serde;
    extern crate serde_aux;
    extern crate serde_json;
    
    use serde::{Deserialize, Serialize};
    use serde_aux::prelude::*;
    
    #[derive(Serialize, Deserialize, Debug, Default)]
    struct MyStruct {
        #[serde(deserialize_with = "deserialize_default_from_empty_object")]
        name: String,
    }
    
    fn main() {
        let s = r#" {"name": "George" }"#;
        let a: MyStruct = serde_json::from_str(s).unwrap();
        assert_eq!(a.name, "George");
    
        let s = r#" { "name": {} } "#;
        let a: MyStruct = serde_json::from_str(s).unwrap();
        assert_eq!(a.name, "");
    
        let s = r#" { "name": null} "#;
        let a: MyStruct = serde_json::from_str(s).unwrap();
        assert_eq!(a.name, "");
    }
    

    The error is

    thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("data did not match any variant of untagged enum EmptyOrNot", line: 1, column: 16)', src/main.rs:38:47
    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    

    Strangely, enough the following code does not error, the name field in MyStruct is now wrapped in an Option (as in the documentation example)

    extern crate serde;
    extern crate serde_aux;
    extern crate serde_json;
    
    use serde::{Deserialize, Serialize};
    use serde_aux::prelude::*;
    
    #[derive(Serialize, Deserialize, Debug, Default)]
    struct MyStruct {
        #[serde(deserialize_with = "deserialize_default_from_empty_object")]
        name: Option<String>,
    }
    
    fn main() {
        let s = r#" {"name": "George" }"#;
        let a: MyStruct = serde_json::from_str(s).unwrap();
        assert_eq!(a.name, Some("George".to_owned()));
    
        let s = r#" { "name": {} } "#;
        let a: MyStruct = serde_json::from_str(s).unwrap();
        assert_eq!(a.name, None);
    
        let s = r#" { "name": null} "#;
        let a: MyStruct = serde_json::from_str(s).unwrap();
        assert_eq!(a.name, None);
    }
    
    opened by georgemp 6
  • Provide a way of serializing and deseriaizing a enum number

    Provide a way of serializing and deseriaizing a enum number

    Enum with numbers are not supported by the serde. This is usually done with implementing a macro. This crate could have such a procedural macro which could generate everything on the fly.

    opened by vityafx 6
  • fix: uncomment the 'chrono' feature flag for a function

    fix: uncomment the 'chrono' feature flag for a function

    The line 60 has use chrono::prelude, but the function doesn't have a cfg feature flag.

    https://github.com/vityafx/serde-aux/blob/a5b044e1f8e61292cbdd2cdbbdb490794f5ec982/src/field_attributes.rs#L53-L60

    Found the following error message in a library that uses serde-aux as a dependency.

    serde-aux = { version = "4.1.1", default-features = false }
    
    error[E0433]: failed to resolve: use of undeclared crate or module `chrono`
      --> /home/hari/.cargo/registry/src/github.com-1ecc6299db9ec823/serde-aux-4.1.1/src/field_attributes.rs:60:9
       |
    60 |     use chrono::prelude::*;
       |         ^^^^^^ use of undeclared crate or module `chrono`
    
    error[E0433]: failed to resolve: use of undeclared crate or module `chrono`
      --> /home/hari/.cargo/registry/src/github.com-1ecc6299db9ec823/serde-aux-4.1.1/src/field_attributes.rs:56:13
       |
    56 | ) -> Result<chrono::DateTime<chrono::Utc>, D::Error>
       |             ^^^^^^ use of undeclared crate or module `chrono`
    
    error[E0433]: failed to resolve: use of undeclared crate or module `chrono`
      --> /home/hari/.cargo/registry/src/github.com-1ecc6299db9ec823/serde-aux-4.1.1/src/field_attributes.rs:56:30
       |
    56 | ) -> Result<chrono::DateTime<chrono::Utc>, D::Error>
       |                              ^^^^^^ use of undeclared crate or module `chrono`
    
    error[E0433]: failed to resolve: use of undeclared type `DateTime`
      --> /home/hari/.cargo/registry/src/github.com-1ecc6299db9ec823/serde-aux-4.1.1/src/field_attributes.rs:67:8
       |
    67 |     Ok(DateTime::<Utc>::from_utc(
       |        ^^^^^^^^ use of undeclared type `DateTime`
    
    error[E0433]: failed to resolve: use of undeclared type `NaiveDateTime`
      --> /home/hari/.cargo/registry/src/github.com-1ecc6299db9ec823/serde-aux-4.1.1/src/field_attributes.rs:68:9
       |
    68 |         NaiveDateTime::from_timestamp_opt(seconds, nanos)
       |         ^^^^^^^^^^^^^ use of undeclared type `NaiveDateTime`
    
    error[E0412]: cannot find type `Utc` in this scope
      --> /home/hari/.cargo/registry/src/github.com-1ecc6299db9ec823/serde-aux-4.1.1/src/field_attributes.rs:67:19
       |
    54 | pub fn deserialize_datetime_utc_from_milliseconds<'de, D>(
       |                                                         - help: you might be missing a type parameter: `, Utc`
    ...
    67 |     Ok(DateTime::<Utc>::from_utc(
       |                   ^^^ not found in this scope
    
    error[E0425]: cannot find value `Utc` in this scope
      --> /home/hari/.cargo/registry/src/github.com-1ecc6299db9ec823/serde-aux-4.1.1/src/field_attributes.rs:70:9
       |
    70 |         Utc,
       |         ^^^ not found in this scope
    
    
    opened by hrkrshnn 5
  • field_attributes: add `default_as_true`

    field_attributes: add `default_as_true`

    This adds a default_as_true helper, which allows Serde to default bool fields to true instead of false.

    This has been brought up on Serde's side before, but has no upstream implementation. Some of the discussion is here: https://github.com/serde-rs/serde/issues/1030

    opened by woodruffw 5
  • deserialize_struct_case_insensitive + serde::rename

    deserialize_struct_case_insensitive + serde::rename

    I have encountered strange behavior when deserialize_struct_case_insensitive is used in conjunction with serde::rename. Here is a slightly modified example taken from the deserialize_struct_case_insensitive documentation:

    use serde::Deserialize;
    use serde_aux::prelude::*;
    
    #[derive(Deserialize, Debug)]
    struct AnotherStruct {
        #[serde(rename = "fieldname")] 
        field_name: String,
    }
    #[derive(Deserialize, Debug)]
    struct MyStruct {
        #[serde(deserialize_with = "deserialize_struct_case_insensitive")]
        another_struct: AnotherStruct,
    }
    
    fn main() {
        let s = r#"{ "another_struct": { "FiElDnAmE": "Test example" } }"#;
        let a: MyStruct = serde_json::from_str(s).unwrap();
        assert_eq!(a.another_struct.field_name, "Test example");
    }
    

    In this case everything works as expected, but if #[serde(rename = "fieldname")] is changed to #[serde(rename = "fieldName")] then I get the following error:

    thread 'main' panicked at 'called Result::unwrap() on an Err value: Error("missing field fieldName", line: 1, column: 53)', src/main.rs:17:47

    opened by stanislav-tkach 5
  • Add `deserialize_default_from_empty_object`.

    Add `deserialize_default_from_empty_object`.

    In addition to deserialize_default_from_null, this also treats empty objects ({}) as null.

    Also, I fixed the deserialize_default_from_null. It would actually treat an Err as null because I accidentally simplified the code too much and moved the .unwrap_or from an Option to a Result.

    opened by reitermarkus 5
  • Please add deserialize_datetime_utc_from_seconds

    Please add deserialize_datetime_utc_from_seconds

    It is almost a copy of deserialize_datetime_utc_from_milliseconds, but I found myself implementing it over and over.

    #[cfg(feature = "chrono")]
    pub fn deserialize_datetime_utc_from_seconds<'de, D>(
        deserializer: D,
    ) -> Result<chrono::DateTime<chrono::Utc>, D::Error>
    where
        D: Deserializer<'de>,
    {
        let number = deserialize_number_from_string::<i64, D>(deserializer)?;
    
        Ok(DateTime::<Utc>::from_utc(
            NaiveDateTime::from_timestamp(number, 0),
            Utc,
        ))
    }
    

    I will make a pull request if needed. Thank you

    opened by Lurk 4
  • serde aux function to get names for fields as they are serialized

    serde aux function to get names for fields as they are serialized

    from https://github.com/serde-rs/serde/issues/1110

    Do you prefer a different method name?

    I combined the function to get the field names from structs and enums so its easier to use. It was possible to use the wrong method for the type for the original implementation.

    I will try address any comments.

    opened by ta32 4
  • Question: how to apply deserialize_struct_case_insensitive to a struct?

    Question: how to apply deserialize_struct_case_insensitive to a struct?

    I am a bit confused by deserialize_struct_case_insensitive. It is categorized as a container_attribute in serde-aux's docs. However, the example seems to show it used as a field attribute. If it is a container_attribute, should I be able to do something like this?

    #[derive(PartialEq, Eq, PartialOrd, Ord, Deserialize)]
    #[serde(deserialize_with = "deserialize_struct_case_insensitive")]
    pub struct Manifest {
        name: String,
        version: String,
    }
    
    opened by jlgerber 3
  • deserialize_default_from_empty_object works differently when default tag is set on inner struct

    deserialize_default_from_empty_object works differently when default tag is set on inner struct

    Hi,

    With the example here, if we tag InnerStruct with #[serde(default)], then the test with empty object fails. A default InnerStruct is created on the struct MyStruct, instead of None. I believe the default for an Option is None. So, not sure why a default object is being constructed in place of it. I have added comments to the relevant sections of the code.

    extern crate serde_json;
    extern crate serde_aux;
    extern crate serde;
    
    use serde_aux::prelude::*;
    
    #[derive(Serialize, Deserialize, Debug)]
    struct MyStruct {
        #[serde(deserialize_with = "deserialize_default_from_empty_object")]
        empty_as_default: Option<MyInnerStruct>,
    }
    
    #[derive(Serialize, Deserialize, Debug)]
    #[serde(default)] //Added this, so that mandatory will be set to 0, if the field is missing from json.
    struct MyInnerStruct {
        mandatory: u64,
    }
    
    fn main() {
        let s = r#" { "empty_as_default": { "mandatory": 42 } } "#;
        let a: MyStruct = serde_json::from_str(s).unwrap();
        assert_eq!(a.empty_as_default.unwrap().mandatory, 42);
    
        let s = r#" { "empty_as_default": null } "#;
        let a: MyStruct = serde_json::from_str(s).unwrap();
        assert!(a.empty_as_default.is_none());
    
        let s = r#" { "empty_as_default": {} } "#;
        let a: MyStruct = serde_json::from_str(s).unwrap(); 
        assert!(a.empty_as_default.is_none()); //This assert fails
    
        let s = r#" { "empty_as_default": { "unknown": 42 } } "#;
        assert!(serde_json::from_str::<MyStruct>(s).is_err());
    }
    

    Thanks

    opened by georgemp 10
  • deserialize_struct_case_insensitive not compatible with enums

    deserialize_struct_case_insensitive not compatible with enums

    I've tried:

    #[serde(deserialize_with = "deserialize_struct_case_insensitive")]
    pub enum Foo {
       Bar
    }
    
    pub enum Foo {
       #[serde(deserialize_with = "deserialize_struct_case_insensitive")]
       Bar
    }
    

    but both cases are rejected.

    opened by kornelski 7
Owner
Victor Polevoy
C/C++/Rust systems and application developer, Certified Scrum Professional (CSP).
Victor Polevoy
Serialize/Deserialize tch-rs types with serde

tch-serde: Serialize/Deserialize tch-rs types with serde This crate provides {ser,de}ialization methods for tch-rs common types. docs.rs | crates.io U

null 4 Apr 3, 2022
A SOME/IP serialization format using the serde framework

serde_someip implements SOME/IP ontop of serde use serde::{Serialize, Deserialize}; use serde_someip::SomeIp; use serde_someip::options::ExampleOption

Morten Mey 3 Feb 14, 2022
Rust libraries and tools to help with interoperability and testing of serialization formats based on Serde.

The repository zefchain/serde-reflection is based on Facebook's repository novifinancial/serde-reflection. We are now maintaining the project here and

Zefchain Labs 42 Nov 29, 2022
Serde serializatsiya va deserializatsiyasi yordamida qilingan VCard JSON generatori

Vicardi Serde serializatsiya va deserializatsiyasi yordamida qilingan VCard JSON generatori Haqida Bizning CCTLD tomonidan ishlab chiqilgan sistema IC

UZINFOCOM 5 Sep 20, 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.5k Dec 4, 2022
This library is a pull parser for CommonMark, written in Rust

This library is a pull parser for CommonMark, written in Rust. It comes with a simple command-line tool, useful for rendering to HTML, and is also designed to be easy to use from as a library.

Raph Levien 1.5k Dec 2, 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 295 Nov 29, 2022
A port of the Node.js library json-file-store

A port of the Node.js library json-file-store

Markus Kohlhase 58 Nov 18, 2022
Easy c̵̰͠r̵̛̠ö̴̪s̶̩̒s̵̭̀-t̶̲͝h̶̯̚r̵̺͐e̷̖̽ḁ̴̍d̶̖̔ ȓ̵͙ė̶͎ḟ̴͙e̸̖͛r̶̖͗ë̶̱́ṉ̵̒ĉ̷̥e̷͚̍ s̷̹͌h̷̲̉a̵̭͋r̷̫̊ḭ̵̊n̷̬͂g̵̦̃ f̶̻̊ơ̵̜ṟ̸̈́ R̵̞̋ù̵̺s̷̖̅ţ̸͗!̸̼͋

Rust S̵̓i̸̓n̵̉ I̴n̴f̶e̸r̵n̷a̴l mutability! Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when

null 293 Sep 22, 2022
serde-compatible redis library for Rust

Undis Undis is a serde-compatible redis library for Rust. WIP This project is currently under heavy development. Use it at your own risk. Todo Add #[d

Hyeonu Park 8 Jan 24, 2022
This library implements a type macro for a zero-sized type that is Serde deserializable only from one specific value.

Monostate This library implements a type macro for a zero-sized type that is Serde deserializable only from one specific value. [dependencies] monosta

David Tolnay 120 Oct 10, 2022
A CSV parser for Rust, with Serde support.

csv A fast and flexible CSV reader and writer for Rust, with support for Serde. Dual-licensed under MIT or the UNLICENSE. Documentation https://docs.r

Andrew Gallant 1.3k Nov 26, 2022
Serde support for encoding/decoding rusty_v8 values

Serde support for encoding/decoding rusty_v8 values

Deno Land 34 Nov 28, 2022
Serde is a framework for serializing and deserializing Rust data structures efficiently and generically.

Serde is a framework for serializing and deserializing Rust data structures efficiently and generically.

null 6.4k Nov 28, 2022
Serde support for (rusty_)v8

serde_v8 Serde support for (rusty_)v8 WIP: see denoland/deno#9540 TODO Experiment with KeyCache to optimize struct keys Experiment with external v8 st

Aaron O'Mullan 13 Nov 28, 2022
Easy reading and writing of `serde` structs to/from Google Sheets

serde_sheets Read and write structs directly from google sheets using serde and csv Implement serde::Serialize to write and serde::Deserialize to read

null 5 Jul 20, 2022
Serialize & deserialize device tree binary using serde

serde_device_tree Use serde framework to deserialize Device Tree Blob binary files; no_std compatible. Use this library Run example: cargo run --examp

Luo Jia 20 Aug 20, 2022
Serialize/Deserialize tch-rs types with serde

tch-serde: Serialize/Deserialize tch-rs types with serde This crate provides {ser,de}ialization methods for tch-rs common types. docs.rs | crates.io U

null 4 Apr 3, 2022
A SOME/IP serialization format using the serde framework

serde_someip implements SOME/IP ontop of serde use serde::{Serialize, Deserialize}; use serde_someip::SomeIp; use serde_someip::options::ExampleOption

Morten Mey 3 Feb 14, 2022
serde-like serialization and deserialization of static Rust types in XML

static-xml static-xml is a serde-like serialization and deserialization library for XML, currently written as a layer on top of xml-rs. Status: in ear

Scott Lamb 8 Nov 22, 2022