Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce DeserOpinions #100

Merged
merged 6 commits into from
Oct 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
merge_group:

jobs:
build:
test:
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
Expand All @@ -23,4 +23,5 @@ jobs:
- name: Run tests
shell: bash
run: |
rustup toolchain install nightly --component miri
just
5 changes: 5 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,8 @@ check:
cargo run --features full,ahash --example "$example"
done
popd

just miri

miri:
cargo +nightly miri run --example opinions -F json
5 changes: 5 additions & 0 deletions merde/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ name = "infinite-stack"
path = "examples/infinite-stack.rs"
required-features = ["json"]

[[example]]
name = "opinions"
path = "examples/opinions.rs"
required-features = ["json"]

[dependencies]
merde_core = { version = "7.0.0", path = "../merde_core", optional = true }
merde_json = { version = "6.2.1", path = "../merde_json", optional = true }
Expand Down
77 changes: 77 additions & 0 deletions merde/examples/opinions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
use merde::{CowStr, DeserOpinions, FieldSlot};

fn main() {
let input_precise = r#"
{ "foo_bar": "hello" }
"#;
let o: Owned = merde_json::from_str(input_precise).unwrap();
assert_eq!(o.foo_bar, "hello");
eprintln!("{o:#?}");

let input_camel_case = r#"
{ "fooBar": "hello" }
"#;
let o: Owned = merde_json::from_str(input_camel_case).unwrap();
assert_eq!(o.foo_bar, "hello");
eprintln!("{o:#?}");

let input_too_many_fields = r#"
{ "foo_bar": "hello", "foo_bar2": "world" }
"#;
assert!(merde_json::from_str::<Owned>(input_too_many_fields).is_err());
let o: OwnedRelaxed = merde_json::from_str(input_too_many_fields).unwrap();
assert_eq!(o.foo_bar, "hello");
eprintln!("{o:#?}");

let input_missing_field = r#"
{}
"#;
let o: Owned = merde_json::from_str(input_missing_field).unwrap();
assert_eq!(o.foo_bar, "(default)");
eprintln!("{o:#?}");
}

#[derive(Debug)]
struct Owned {
foo_bar: String,
}

struct OwnedOpinions;

impl DeserOpinions for OwnedOpinions {
fn deny_unknown_fields(&self) -> bool {
true
}

#[allow(clippy::needless_lifetimes)]
fn default_field_value<'s, 'borrow>(&self, key: &'borrow str, slot: FieldSlot<'s, 'borrow>) {
if key == "foo_bar" {
slot.fill::<String>("(default)".into());
}
}

fn map_key_name<'s>(&self, key: CowStr<'s>) -> CowStr<'s> {
if key == "fooBar" {
CowStr::Owned("foo_bar".into())
} else {
key
}
}
}

merde::derive! {
impl (Deserialize) for struct Owned {
foo_bar
} via OwnedOpinions
}

#[derive(Debug)]
struct OwnedRelaxed {
foo_bar: String,
}

merde::derive! {
impl (Deserialize) for struct OwnedRelaxed {
foo_bar
}
}
Loading