use std::{any::Any, rc::Rc, sync::Arc};
use ploidy_pointer::{JsonPointee, JsonPointer};
#[test]
fn test_rename_field() {
#[derive(JsonPointee)]
struct MyStruct {
#[ploidy(pointer(rename = "customName"))]
my_field: String,
}
let s = MyStruct {
my_field: "hello".to_owned(),
};
let pointer = JsonPointer::parse("/customName").unwrap();
let result = s.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
let pointer = JsonPointer::parse("/my_field").unwrap();
assert!(s.resolve(pointer).is_err());
}
#[test]
fn test_rename_all_snake_case() {
#[derive(JsonPointee)]
#[ploidy(pointer(rename_all = "snake_case"))]
struct MyStruct {
my_field: String,
another_field: i32,
}
let s = MyStruct {
my_field: "hello".to_owned(),
another_field: 42,
};
let pointer = JsonPointer::parse("/my_field").unwrap();
assert!(s.resolve(pointer).is_ok());
let pointer = JsonPointer::parse("/another_field").unwrap();
assert!(s.resolve(pointer).is_ok());
}
#[test]
fn test_rename_all_camel_case() {
#[derive(JsonPointee)]
#[ploidy(pointer(rename_all = "camelCase"))]
struct MyStruct {
my_field: String,
another_field: i32,
}
let s = MyStruct {
my_field: "hello".to_owned(),
another_field: 42,
};
let pointer = JsonPointer::parse("/myField").unwrap();
let result = s.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
let pointer = JsonPointer::parse("/anotherField").unwrap();
let result = s.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<i32>(), Some(&42));
let pointer = JsonPointer::parse("/my_field").unwrap();
assert!(s.resolve(pointer).is_err());
}
#[test]
fn test_rename_all_pascal_case() {
#[derive(JsonPointee)]
#[ploidy(pointer(rename_all = "PascalCase"))]
struct MyStruct {
my_field: String,
another_field: i32,
}
let s = MyStruct {
my_field: "hello".to_owned(),
another_field: 42,
};
let pointer = JsonPointer::parse("/MyField").unwrap();
assert!(s.resolve(pointer).is_ok());
let pointer = JsonPointer::parse("/AnotherField").unwrap();
assert!(s.resolve(pointer).is_ok());
}
#[test]
fn test_rename_all_kebab_case() {
#[derive(JsonPointee)]
#[ploidy(pointer(rename_all = "kebab-case"))]
struct MyStruct {
my_field: String,
another_field: i32,
}
let s = MyStruct {
my_field: "hello".to_owned(),
another_field: 42,
};
let pointer = JsonPointer::parse("/my-field").unwrap();
assert!(s.resolve(pointer).is_ok());
let pointer = JsonPointer::parse("/another-field").unwrap();
assert!(s.resolve(pointer).is_ok());
}
#[test]
fn test_rename_overrides_rename_all() {
#[derive(JsonPointee)]
#[ploidy(pointer(rename_all = "camelCase"))]
struct MyStruct {
#[ploidy(pointer(rename = "customName"))]
my_field: String,
another_field: i32,
}
let s = MyStruct {
my_field: "hello".to_owned(),
another_field: 42,
};
let pointer = JsonPointer::parse("/customName").unwrap();
assert!(s.resolve(pointer).is_ok());
let pointer = JsonPointer::parse("/anotherField").unwrap();
assert!(s.resolve(pointer).is_ok());
let pointer = JsonPointer::parse("/my_field").unwrap();
assert!(s.resolve(pointer).is_err());
let pointer = JsonPointer::parse("/another_field").unwrap();
assert!(s.resolve(pointer).is_err());
}
#[test]
fn test_enum_with_rename() {
#[derive(JsonPointee)]
#[ploidy(pointer(untagged, rename_all = "camelCase"))]
enum MyEnum {
VariantA { my_field: String },
VariantB { another_field: i32 },
}
let e = MyEnum::VariantA {
my_field: "hello".to_owned(),
};
let pointer = JsonPointer::parse("/myField").unwrap();
let result = e.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
let pointer = JsonPointer::parse("/my_field").unwrap();
assert!(e.resolve(pointer).is_err());
let e = MyEnum::VariantB { another_field: 123 };
let pointer = JsonPointer::parse("/anotherField").unwrap();
let result = e.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<i32>(), Some(&123));
}
#[test]
fn test_flatten_field() {
#[derive(JsonPointee)]
struct Inner {
inner_field: String,
}
#[derive(JsonPointee)]
struct Outer {
#[ploidy(pointer(flatten))]
inner: Inner,
}
let outer = Outer {
inner: Inner {
inner_field: "hello".to_owned(),
},
};
let pointer = JsonPointer::parse("/inner_field").unwrap();
let result = outer.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
}
#[test]
fn test_multiple_flattened_fields() {
#[derive(JsonPointee)]
struct Inner1 {
field1: String,
}
#[derive(JsonPointee)]
struct Inner2 {
field2: i32,
}
#[derive(JsonPointee)]
struct Outer {
#[ploidy(pointer(flatten))]
inner1: Inner1,
#[ploidy(pointer(flatten))]
inner2: Inner2,
}
let outer = Outer {
inner1: Inner1 {
field1: "hello".to_owned(),
},
inner2: Inner2 { field2: 42 },
};
let pointer = JsonPointer::parse("/field1").unwrap();
let result = outer.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
let pointer = JsonPointer::parse("/field2").unwrap();
let result = outer.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<i32>(), Some(&42));
}
#[test]
fn test_priority_regular_over_flattened() {
#[derive(JsonPointee)]
struct Inner {
my_field: String,
}
#[derive(JsonPointee)]
struct Outer {
my_field: i32,
#[ploidy(pointer(flatten))]
inner: Inner,
}
let outer = Outer {
my_field: 42,
inner: Inner {
my_field: "hello".to_owned(),
},
};
let pointer = JsonPointer::parse("/my_field").unwrap();
let result = outer.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<i32>(), Some(&42));
}
#[test]
fn test_nested_flattening() {
#[derive(JsonPointee)]
struct Deep {
deep_field: String,
}
#[derive(JsonPointee)]
struct Middle {
#[ploidy(pointer(flatten))]
deep: Deep,
}
#[derive(JsonPointee)]
struct Outer {
#[ploidy(pointer(flatten))]
middle: Middle,
}
let outer = Outer {
middle: Middle {
deep: Deep {
deep_field: "hello".to_owned(),
},
},
};
let pointer = JsonPointer::parse("/deep_field").unwrap();
let result = outer.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
}
#[test]
fn test_flatten_error_not_found() {
#[derive(JsonPointee)]
struct Inner {
inner_field: String,
}
#[derive(JsonPointee)]
struct Outer {
regular_field: i32,
#[ploidy(pointer(flatten))]
inner: Inner,
}
let outer = Outer {
regular_field: 42,
inner: Inner {
inner_field: "hello".to_owned(),
},
};
let pointer = JsonPointer::parse("/nonexistent").unwrap();
assert!(outer.resolve(pointer).is_err());
}
#[test]
fn test_enum_variant_flatten() {
#[derive(JsonPointee)]
struct Inner {
inner_field: String,
}
#[derive(JsonPointee)]
#[ploidy(pointer(untagged))]
enum MyEnum {
VariantA {
regular_field: i32,
#[ploidy(pointer(flatten))]
inner: Inner,
},
}
let e = MyEnum::VariantA {
regular_field: 42,
inner: Inner {
inner_field: "hello".to_owned(),
},
};
let pointer = JsonPointer::parse("/regular_field").unwrap();
let result = e.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<i32>(), Some(&42));
let pointer = JsonPointer::parse("/inner_field").unwrap();
let result = e.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
}
#[test]
fn test_flatten_with_rename_all() {
#[derive(JsonPointee)]
#[ploidy(pointer(rename_all = "camelCase"))]
struct Inner {
inner_field: String,
}
#[derive(JsonPointee)]
#[ploidy(pointer(rename_all = "camelCase"))]
struct Outer {
regular_field: i32,
#[ploidy(pointer(flatten))]
inner: Inner,
}
let outer = Outer {
regular_field: 42,
inner: Inner {
inner_field: "hello".to_owned(),
},
};
let pointer = JsonPointer::parse("/regularField").unwrap();
let result = outer.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<i32>(), Some(&42));
let pointer = JsonPointer::parse("/innerField").unwrap();
let result = outer.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
}
#[test]
fn test_flatten_order_matters() {
#[derive(JsonPointee)]
struct Inner1 {
shared_field: String,
}
#[derive(JsonPointee)]
struct Inner2 {
shared_field: i32,
}
#[derive(JsonPointee)]
struct Outer {
#[ploidy(pointer(flatten))]
inner1: Inner1,
#[ploidy(pointer(flatten))]
inner2: Inner2,
}
let outer = Outer {
inner1: Inner1 {
shared_field: "hello".to_owned(),
},
inner2: Inner2 { shared_field: 42 },
};
let pointer = JsonPointer::parse("/shared_field").unwrap();
let result = outer.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
}
#[test]
#[cfg(feature = "chrono")]
fn test_pointer_to_chrono_datetime() {
use chrono::{DateTime, Utc};
let timestamp: DateTime<Utc> = "2024-01-15T10:30:00Z".parse().unwrap();
let pointer = JsonPointer::parse("").unwrap();
let result = timestamp.resolve(pointer).unwrap() as &dyn Any;
assert!(result.is::<DateTime<Utc>>());
let pointer = JsonPointer::parse("/foo").unwrap();
assert!(timestamp.resolve(pointer).is_err());
}
#[test]
#[cfg(feature = "url")]
fn test_pointer_to_url() {
use url::Url;
let url = Url::parse("https://example.com/path?query=value").unwrap();
let pointer = JsonPointer::parse("").unwrap();
let result = url.resolve(pointer).unwrap() as &dyn Any;
assert!(result.is::<Url>());
let pointer = JsonPointer::parse("/foo").unwrap();
assert!(url.resolve(pointer).is_err());
}
#[test]
#[cfg(feature = "serde_json")]
fn test_pointer_to_serde_json() {
use serde_json::json;
let data = json!({
"name": "Alice",
"age": 30,
"items": [1, 2, 3],
"nested": {
"field": "value"
}
});
let pointer = JsonPointer::parse("/name").unwrap();
let result = data.resolve(pointer).unwrap() as &dyn Any;
assert!(result.is::<serde_json::Value>());
let pointer = JsonPointer::parse("/items/1").unwrap();
let result = data.resolve(pointer).unwrap() as &dyn Any;
assert!(result.is::<serde_json::Value>());
let pointer = JsonPointer::parse("/nested/field").unwrap();
let result = data.resolve(pointer).unwrap() as &dyn Any;
assert!(result.is::<serde_json::Value>());
let pointer = JsonPointer::parse("").unwrap();
let result = data.resolve(pointer).unwrap() as &dyn Any;
assert!(result.is::<serde_json::Value>());
let pointer = JsonPointer::parse("/nonexistent").unwrap();
assert!(data.resolve(pointer).is_err());
let pointer = JsonPointer::parse("/items/10").unwrap();
assert!(data.resolve(pointer).is_err());
}
#[test]
#[cfg(feature = "indexmap")]
fn test_indexmap() {
use indexmap::IndexMap;
let mut map = IndexMap::new();
map.insert("first".to_string(), 10);
map.insert("second".to_string(), 20);
map.insert("third".to_string(), 30);
let pointer = JsonPointer::parse("/first").unwrap();
let result = map.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<i32>(), Some(&10));
let pointer = JsonPointer::parse("/second").unwrap();
let result = map.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<i32>(), Some(&20));
let pointer = JsonPointer::parse("").unwrap();
let result = map.resolve(pointer).unwrap() as &dyn Any;
assert!(result.is::<IndexMap<String, i32>>());
let pointer = JsonPointer::parse("/nonexistent").unwrap();
assert!(map.resolve(pointer).is_err());
}
#[test]
fn test_skip_field() {
#[derive(JsonPointee)]
struct MyStruct {
visible: String,
#[ploidy(pointer(skip))]
hidden: String,
}
let s = MyStruct {
visible: "hello".to_owned(),
hidden: "secret".to_owned(),
};
let pointer = JsonPointer::parse("/visible").unwrap();
let result = s.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
let pointer = JsonPointer::parse("/hidden").unwrap();
assert!(s.resolve(pointer).is_err());
let pointer = JsonPointer::parse("").unwrap();
assert!(s.resolve(pointer).is_ok());
}
#[test]
#[cfg(feature = "did-you-mean")]
fn test_skip_not_in_suggestions() {
#[derive(JsonPointee)]
struct MyStruct {
visible: String,
#[ploidy(pointer(skip))]
hidden: String,
}
let s = MyStruct {
visible: "hello".to_owned(),
hidden: "secret".to_owned(),
};
let pointer = JsonPointer::parse("/nonexistent").unwrap();
match s.resolve(pointer) {
Err(ploidy_pointer::JsonPointeeError::Key(key_err)) => {
assert_eq!(
key_err
.context
.as_ref()
.and_then(|c| c.suggestion.as_deref()),
Some("visible")
);
}
_ => panic!("expected `JsonPointerError::Key` error"),
}
}
#[test]
fn test_skip_with_rename_all() {
#[derive(JsonPointee)]
#[ploidy(pointer(rename_all = "camelCase"))]
struct MyStruct {
my_field: String,
#[ploidy(pointer(skip))]
hidden_field: String,
}
let s = MyStruct {
my_field: "hello".to_owned(),
hidden_field: "secret".to_owned(),
};
let pointer = JsonPointer::parse("/myField").unwrap();
let result = s.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
let pointer = JsonPointer::parse("/hiddenField").unwrap();
assert!(s.resolve(pointer).is_err());
let pointer = JsonPointer::parse("/hidden_field").unwrap();
assert!(s.resolve(pointer).is_err());
}
#[test]
fn test_multiple_skip_fields() {
#[derive(JsonPointee)]
struct MyStruct {
visible1: String,
#[ploidy(pointer(skip))]
hidden1: String,
visible2: i32,
#[ploidy(pointer(skip))]
hidden2: i32,
}
let s = MyStruct {
visible1: "hello".to_owned(),
hidden1: "secret1".to_owned(),
visible2: 42,
hidden2: 99,
};
let pointer = JsonPointer::parse("/visible1").unwrap();
assert!(s.resolve(pointer).is_ok());
let pointer = JsonPointer::parse("/visible2").unwrap();
assert!(s.resolve(pointer).is_ok());
let pointer = JsonPointer::parse("/hidden1").unwrap();
assert!(s.resolve(pointer).is_err());
let pointer = JsonPointer::parse("/hidden2").unwrap();
assert!(s.resolve(pointer).is_err());
}
#[test]
fn test_skip_and_flatten_on_different_fields() {
#[derive(JsonPointee)]
struct Inner {
inner_field: String,
}
#[derive(JsonPointee)]
struct Outer {
#[ploidy(pointer(skip))]
hidden: String,
#[ploidy(pointer(flatten))]
inner: Inner,
visible: i32,
}
let outer = Outer {
hidden: "secret".to_owned(),
inner: Inner {
inner_field: "hello".to_owned(),
},
visible: 42,
};
let pointer = JsonPointer::parse("/inner_field").unwrap();
let result = outer.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
let pointer = JsonPointer::parse("/visible").unwrap();
let result = outer.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<i32>(), Some(&42));
let pointer = JsonPointer::parse("/hidden").unwrap();
assert!(outer.resolve(pointer).is_err());
}
#[test]
fn test_skip_in_enum_variant() {
#[derive(JsonPointee)]
#[ploidy(pointer(untagged))]
enum MyEnum {
VariantA {
visible: String,
#[ploidy(pointer(skip))]
hidden: String,
},
}
let e = MyEnum::VariantA {
visible: "hello".to_owned(),
hidden: "secret".to_owned(),
};
let pointer = JsonPointer::parse("/visible").unwrap();
let result = e.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
let pointer = JsonPointer::parse("/hidden").unwrap();
assert!(e.resolve(pointer).is_err());
}
#[test]
fn test_skip_in_tuple_struct() {
#[derive(JsonPointee)]
struct MyTuple(String, #[ploidy(pointer(skip))] String, i32);
let t = MyTuple("hello".to_owned(), "secret".to_owned(), 42);
let pointer = JsonPointer::parse("/0").unwrap();
let result = t.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
let pointer = JsonPointer::parse("/1").unwrap();
assert!(t.resolve(pointer).is_err());
let pointer = JsonPointer::parse("/2").unwrap();
let result = t.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<i32>(), Some(&42));
}
#[test]
fn test_all_fields_skipped() {
#[derive(JsonPointee)]
struct AllHidden {
#[ploidy(pointer(skip))]
field1: String,
#[ploidy(pointer(skip))]
field2: i32,
}
let s = AllHidden {
field1: "secret".to_owned(),
field2: 42,
};
let pointer = JsonPointer::parse("").unwrap();
assert!(s.resolve(pointer).is_ok());
let pointer = JsonPointer::parse("/field1").unwrap();
assert!(s.resolve(pointer).is_err());
let pointer = JsonPointer::parse("/field2").unwrap();
assert!(s.resolve(pointer).is_err());
}
#[test]
fn test_skip_unit_variant() {
#[derive(JsonPointee)]
#[ploidy(pointer(untagged))]
enum MyEnum {
Active,
#[ploidy(pointer(skip))]
Inactive,
}
let e = MyEnum::Inactive;
let pointer = JsonPointer::parse("").unwrap();
assert!(e.resolve(pointer).is_err());
let e = MyEnum::Active;
let pointer = JsonPointer::parse("").unwrap();
assert!(e.resolve(pointer).is_ok());
}
#[test]
fn test_skip_newtype_variant() {
#[derive(JsonPointee)]
#[ploidy(pointer(untagged))]
#[allow(dead_code)]
enum MyEnum {
Value(String),
#[ploidy(pointer(skip))]
Ref(String),
}
let e = MyEnum::Ref("test".to_owned());
let pointer = JsonPointer::parse("").unwrap();
assert!(e.resolve(pointer).is_err());
let e = MyEnum::Value("hello".to_owned());
let pointer = JsonPointer::parse("").unwrap();
let result = e.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
}
#[test]
fn test_skip_struct_variant() {
#[derive(JsonPointee)]
#[ploidy(pointer(untagged))]
#[allow(dead_code)]
enum MyEnum {
Active {
field: String,
},
#[ploidy(pointer(skip))]
Inactive {
field: String,
},
}
let e = MyEnum::Inactive {
field: "test".to_owned(),
};
let pointer = JsonPointer::parse("/field").unwrap();
assert!(e.resolve(pointer).is_err());
let pointer = JsonPointer::parse("").unwrap();
assert!(e.resolve(pointer).is_err());
let e = MyEnum::Active {
field: "hello".to_owned(),
};
let pointer = JsonPointer::parse("/field").unwrap();
let result = e.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
}
#[test]
fn test_multiple_variants_with_skip() {
#[derive(JsonPointee)]
#[ploidy(pointer(untagged))]
#[allow(dead_code)]
enum Status {
Active {
count: i32,
},
#[ploidy(pointer(skip))]
Pending,
#[ploidy(pointer(skip))]
Deleted {
reason: String,
},
Archived {
date: String,
},
}
let s = Status::Active { count: 42 };
assert!(s.resolve(JsonPointer::parse("/count").unwrap()).is_ok());
let s = Status::Pending;
assert!(s.resolve(JsonPointer::parse("").unwrap()).is_err());
let s = Status::Deleted {
reason: "test".to_owned(),
};
assert!(s.resolve(JsonPointer::parse("").unwrap()).is_err());
assert!(s.resolve(JsonPointer::parse("/reason").unwrap()).is_err());
let s = Status::Archived {
date: "2024".to_owned(),
};
assert!(s.resolve(JsonPointer::parse("/date").unwrap()).is_ok());
}
#[test]
fn test_generic_type_with_bounds() {
#[derive(JsonPointee)]
#[ploidy(pointer(untagged))]
enum GenericWrapper<T> {
Value(T),
None,
}
#[derive(JsonPointee)]
struct Inner {
field: String,
}
let wrapped = GenericWrapper::Value(Inner {
field: "hello".to_owned(),
});
let pointer = JsonPointer::parse("").unwrap();
assert!(wrapped.resolve(pointer).is_ok());
let pointer = JsonPointer::parse("/field").unwrap();
let result = wrapped.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
let wrapped: GenericWrapper<Inner> = GenericWrapper::None;
let pointer = JsonPointer::parse("").unwrap();
assert!(wrapped.resolve(pointer).is_ok());
}
#[test]
fn test_generic_struct_with_bounds() {
#[derive(JsonPointee)]
struct Container<T> {
value: T,
name: String,
}
#[derive(JsonPointee)]
struct Item {
id: i32,
}
let container = Container {
value: Item { id: 42 },
name: "test".to_owned(),
};
let pointer = JsonPointer::parse("/name").unwrap();
let result = container.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"test".to_owned()));
let pointer = JsonPointer::parse("/value/id").unwrap();
let result = container.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<i32>(), Some(&42));
}
#[test]
fn test_multiple_generic_parameters_with_bounds() {
#[derive(JsonPointee)]
struct Pair<A, B> {
first: A,
second: B,
}
#[derive(JsonPointee)]
struct Left {
left_value: String,
}
#[derive(JsonPointee)]
struct Right {
right_value: i32,
}
let pair = Pair {
first: Left {
left_value: "left".to_owned(),
},
second: Right { right_value: 100 },
};
let pointer = JsonPointer::parse("/first/left_value").unwrap();
let result = pair.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"left".to_owned()));
let pointer = JsonPointer::parse("/second/right_value").unwrap();
let result = pair.resolve(pointer).unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<i32>(), Some(&100));
}
#[test]
fn test_downcast_box() {
#[derive(JsonPointee)]
struct Inner {
value: String,
}
let boxed = Box::new(Inner {
value: "hello".to_owned(),
});
let pointee = boxed.resolve(JsonPointer::empty()).unwrap() as &dyn Any;
assert!(pointee.downcast_ref::<Inner>().is_some());
assert!(pointee.downcast_ref::<Box<Inner>>().is_none());
}
#[test]
fn test_downcast_arc() {
#[derive(JsonPointee)]
struct Inner {
value: String,
}
let arced = Arc::new(Inner {
value: "hello".to_owned(),
});
let pointee = arced.resolve(JsonPointer::empty()).unwrap() as &dyn Any;
assert!(pointee.downcast_ref::<Inner>().is_some());
assert!(pointee.downcast_ref::<Arc<Inner>>().is_none());
}
#[test]
fn test_downcast_rc() {
#[derive(JsonPointee)]
struct Inner {
value: String,
}
let rced = Rc::new(Inner {
value: "hello".to_owned(),
});
let pointee = rced.resolve(JsonPointer::empty()).unwrap() as &dyn Any;
assert!(pointee.downcast_ref::<Inner>().is_some());
assert!(pointee.downcast_ref::<Rc<Inner>>().is_none());
}
#[test]
fn test_box_resolve_is_transparent() {
#[derive(JsonPointee)]
struct Inner {
value: String,
}
let boxed: Box<Inner> = Box::new(Inner {
value: "hello".to_owned(),
});
let result = boxed
.resolve(JsonPointer::parse("/value").unwrap())
.unwrap() as &dyn Any;
assert_eq!(result.downcast_ref::<String>(), Some(&"hello".to_owned()));
}
#[test]
fn test_option_resolve_is_transparent() {
#[derive(Debug, Eq, JsonPointee, PartialEq)]
struct Inner {
value: String,
}
let some = Some(Inner {
value: "hello".to_owned(),
});
let inner = some.resolve(JsonPointer::empty()).unwrap() as &dyn Any;
assert_eq!(inner.downcast_ref::<Inner>(), some.as_ref());
let value = some.resolve(JsonPointer::parse("/value").unwrap()).unwrap() as &dyn Any;
assert_eq!(value.downcast_ref::<String>(), Some(&"hello".to_owned()));
let none = None::<Inner>;
assert!(none.resolve(JsonPointer::empty()).is_err());
}