Skip to content

Commit

Permalink
Expand Structable/Enumerable tests; fix Structable Debug impl (#7)
Browse files Browse the repository at this point in the history
  • Loading branch information
carllerche committed May 10, 2021
1 parent 7a38168 commit 7640b04
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 28 deletions.
47 changes: 46 additions & 1 deletion tests/tests/enumerable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use valuable::field::*;
use valuable::*;

#[test]
fn test_manual_impl() {
fn test_manual_static_impl() {
enum Enum {
Struct { x: &'static str },
Tuple(u8),
Expand Down Expand Up @@ -52,3 +52,48 @@ fn test_manual_impl() {
let v = Enum::Unit;
assert_eq!(format!("{:?}", v.as_value()), r#"Enum::Unit"#);
}

#[test]
#[ignore]
fn test_manual_dyn_impl() {
todo!();
}

#[test]
fn test_variant_named_field() {
let name = "my_field".to_string();
let fields = [NamedField::new(&name[..])];
let variant = VariantDef::new("Hello", Fields::Named(&fields[..]), false);

assert_eq!(variant.name(), "Hello");
assert!(!variant.is_dynamic());

match *variant.fields() {
Fields::Named(f) => {
assert!(std::ptr::eq((&fields[..]).as_ptr(), f.as_ptr(),));
}
_ => panic!(),
}
}

#[test]
fn test_variant_unnamed_field() {
let variant = VariantDef::new("Hello", Fields::Unnamed, false);

assert_eq!(variant.name(), "Hello");
assert!(!variant.is_dynamic());
assert!(matches!(variant.fields(), Fields::Unnamed));
}

#[test]
fn test_enum_def() {
let fields = [NamedField::new("foo")];
let a = VariantDef::new("A", Fields::Named(&fields[..]), false);
let b = VariantDef::new("B", Fields::Unnamed, false);
let variants = [a, b];
let def = EnumDef::new("Foo", &variants, false);

assert_eq!(def.name(), "Foo");
assert!(std::ptr::eq(variants.as_ptr(), def.variants().as_ptr(),));
assert!(!def.is_dynamic());
}
35 changes: 35 additions & 0 deletions tests/tests/structable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,41 @@ fn test_manual_static_impl() {
);
}

#[test]
fn test_manual_dyn_impl() {
struct MyStruct;

impl Valuable for MyStruct {
fn as_value(&self) -> Value<'_> {
Value::Structable(self)
}

fn visit(&self, visit: &mut dyn Visit) {
visit.visit_named_fields(&NamedValues::new(
&[NamedField::new("foo")],
&[Value::U32(1)],
));
visit.visit_named_fields(&NamedValues::new(
&[NamedField::new("bar")],
&[Value::String("two")],
));
}
}

impl Structable for MyStruct {
fn definition(&self) -> StructDef<'_> {
StructDef::new("MyStruct", Fields::NamedStatic(&[]), true)
}
}

let my_struct = MyStruct;

assert_eq!(
format!("{:?}", my_struct.as_value()),
"MyStruct { foo: 1, bar: \"two\" }"
);
}

#[test]
fn test_named_field() {
let name = "hello".to_string();
Expand Down
60 changes: 33 additions & 27 deletions valuable/src/structable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,43 +20,49 @@ pub struct StructDef<'a> {

impl fmt::Debug for dyn Structable + '_ {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
struct DebugStruct<'a, 'b> {
name: &'b str,
fmt: &'b mut fmt::Formatter<'a>,
res: fmt::Result,
}
let def = self.definition();

if def.fields().is_named() {
struct DebugStruct<'a, 'b> {
fmt: fmt::DebugStruct<'a, 'b>,
}

impl Visit for DebugStruct<'_, '_> {
fn visit_named_fields(&mut self, record: &NamedValues<'_>) {
let mut d = self.fmt.debug_struct(self.name);
let mut debug = DebugStruct {
fmt: fmt.debug_struct(def.name()),
};

for (field, value) in record.entries() {
d.field(field.name(), value);
impl Visit for DebugStruct<'_, '_> {
fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
for (field, value) in named_values.entries() {
self.fmt.field(field.name(), value);
}
}
}

self.visit(&mut debug);

self.res = d.finish();
debug.fmt.finish()
} else {
struct DebugStruct<'a, 'b> {
fmt: fmt::DebugTuple<'a, 'b>,
}

fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
let mut d = self.fmt.debug_tuple(self.name);
let mut debug = DebugStruct {
fmt: fmt.debug_tuple(def.name()),
};

for value in values {
d.field(value);
impl Visit for DebugStruct<'_, '_> {
fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
for value in values {
self.fmt.field(value);
}
}

self.res = d.finish();
}
}

let def = self.definition();
let mut visit = DebugStruct {
name: def.name(),
fmt,
res: Ok(()),
};

self.visit(&mut visit);
visit.res
self.visit(&mut debug);

debug.fmt.finish()
}
}
}

Expand Down

0 comments on commit 7640b04

Please sign in to comment.