Coder Social home page Coder Social logo

obake's People

Contributors

doctorn avatar jam1garner avatar janpetschexain avatar samvrlewis avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

obake's Issues

Add serde versioned derive

The main use I'd have for this crate is to version config files (as described in the readme) but there doesn't currently appear to be a mechanism for attempting to attempt to parse as any version (in order to then upgrade it).

Currently it requires something along the lines of:

let x: Foo  = toml::from_str(content)
    .map(<Foo as obake::Versioned>::Versioned::Foo_v0_2_0)
    .or_else(|_| {
        toml::from_str(content)
            .map(<Foo as obake::Versioned>::Versioned::Foo_v0_1_0)
    })?
    .into();

This ofc gets a bit repetitive (the above is only 2 versions!) and while it would require a bit of special-casing, it'd be preferable for the above to be possible to derive serde traits for the Versioned enum.

Alternatively you could provide a mechanism for running a function polymorphic over its return type over each version in sequence until one returns Ok.

This could look something like:

let x = Foo::for_all_versions(toml::from_str)(content)?;

Also worth noting (as I'm sure you're away) that if you derive serde traits for the enum using #[obake(derive(Serialize, Deserialize))] it will ofc expect you to describe an version such as:

[Foo_v0_1_0]
foo = 'foo'
baz = 'x'

Deserialzing `untagged` versions should default to latest version (not earliest)

Hi! This library is so useful, but I'm failing to use it with serde_json. I've tried the following way:

use serde_json::json;
use obake;

#[obake::versioned]
#[obake(version("0.1.0"))]
#[obake(version("0.2.0"))]
#[obake(version("0.3.0"))]
#[obake(derive(Debug, PartialEq, serde::Serialize, serde::Deserialize))]
#[obake(serde(untagged))]
#[derive(Debug, Default, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
struct Character {
    name: String,
    age: u32,
    #[obake(cfg(">=0.2.0"))]
    height: f32,
    #[obake(cfg(">=0.3.0"))]
    weight: f32,
}

impl From<Character!["0.1.0"]> for Character!["0.2.0"] {
    fn from(old: Character!["0.1.0"]) -> Self {
        Self {
            name: old.name,
            age: old.age,
            ..Default::default()
        }
    }
}

impl From<Character!["0.2.0"]> for Character!["0.3.0"] {
    fn from(old: Character!["0.2.0"]) -> Self {
        Self {
            name: old.name,
            age: old.age,
            height: old.height,
            ..Default::default()
        }
    }
}

fn main() {}

#[cfg(test)]
mod tests {
    use serde_json::json;
    use crate::*;

    #[test]
    fn from_2_to_3() {
        let freeza_ser = serde_json::to_string_pretty(&json!({
            "name": "Freeza",
            "age": 32,
            "height": 1.53,
        })).unwrap();
        dbg!(&freeza_ser);

        let freeza: VersionedCharacter = serde_json::from_str(&freeza_ser).unwrap();
        dbg!(&freeza);
        let freeza: Character = freeza.into();
        dbg!(&freeza);

        let freeza_expected = Character {
            name: "Freeza".into(),
            age: 32,
            height: 1.53,
            weight: 0.,
        };
        assert_eq!(&freeza_expected, &freeza);
    }
}

The output is:

failures:

---- tests::from_2_to_3 stdout ----
[src/main.rs:56] &freeza_ser = "{\n  \"age\": 32,\n  \"height\": 1.53,\n  \"name\": \"Freeza\"\n}"
[src/main.rs:59] &freeza = Character_v0_1_0(
    Character_v0_1_0 {
        name: "Freeza",
        age: 32,
    },
)
[src/main.rs:61] &freeza = Character_v0_3_0 {
    name: "Freeza",
    age: 32,
    height: 0.0,
    weight: 0.0,
}
thread 'tests::from_2_to_3' panicked at 'assertion failed: `(left == right)`
  left: `Character_v0_3_0 { name: "Freeza", age: 32, height: 1.53, weight: 0.0 }`,
 right: `Character_v0_3_0 { name: "Freeza", age: 32, height: 0.0, weight: 0.0 }`', src/main.rs:69:9

So, the current behavior is that serde_json::from_str::<VersionedCharacter>(&freeza_ser) is deserializing into the first version, and I want it to deserialize like the following:

fn character_parser(serialized_data: &String) -> Character {
    if let Ok(data) = serde_json::from_str::<Character!["0.3.0"]>(&serialized_data) {
        return data;
    }

    if let Ok(data) = serde_json::from_str::<Character!["0.2.0"]>(&serialized_data) {
        let data: Character!["0.3.0"] = data.into();
        return data;
    }

    if let Ok(data) = serde_json::from_str::<Character!["0.1.0"]>(&serialized_data) {
        let data: Character!["0.2.0"] = data.into();
        let data: Character!["0.3.0"] = data.into();
        return data;
    }

    return Character::default();
}

Am I missing something crucial here? Is there any way for this lib to implement that parsing automatically?

Thank you!

Add type alias for accessing Versioned enum

I believe it would be desirable to provide an alias such as:

pub type AnyVersion<T> = <T as obake::Versioned>::Versioned;

reasoning:

  • less eye-sore
  • "reads" better, making it easier for new users to understand
  • removes redundancy of typing out "Versioned" twice, which honestly took me all of 5 minutes to get sick of :P

Willing to PR such a change but didn't want to so without first seeing if it's desirable. Name is just the first thing I thought of and ultimately not important if you have one in mind.

How to remove fields (or change type)

I am trying to remove the field

#[derive(Deserialize, Serialize, Debug, PartialEq)]
#[obake::versioned]
#[obake(version("0.1.0"))]
#[obake(version("0.2.0"))]
pub struct Test {
  #[obake(cfg("0.1.0"))]
  pub foo: u16,
  pub bar: Vec<u16>,
}

impl From<Test!["0.1.0"]> for Test!["0.2.0"] {
  fn from(this: Test!["0.1.0"]) -> Self {
    Self { bar: this.bar }
  }
}

The error is

15 |   pub foo: u16,
   |       ^^^ `Test_v0_2_0` does not have this field
   |
   = note: all struct fields are already assigned

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.