Skip to content

Commit

Permalink
add Tuplable (#49)
Browse files Browse the repository at this point in the history
  • Loading branch information
carllerche authored Jun 1, 2021
1 parent 93fbaa4 commit b1e12a9
Show file tree
Hide file tree
Showing 8 changed files with 445 additions and 46 deletions.
89 changes: 89 additions & 0 deletions tests/tests/tuplable.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use valuable::*;

macro_rules! test_tuple {
(
$(
$name:ident => $num:expr, $tuple:expr;
)*
) => {
$(
#[test]
fn $name() {
let tuple = $tuple;

assert_eq!(format!("{:?}", tuple.as_value()), format!("{:?}", tuple),);

let def = tuple.definition();

assert_eq!(def.is_unit(), $num == 0);
assert!(def.is_static());
assert!(matches!(def, TupleDef::Static { fields, .. } if fields == $num));

let counts = tests::visit_counts(&tuple);
assert_eq!(
counts,
tests::VisitCount {
visit_unnamed_fields: 1,
..Default::default()
}
);
}
)*
};
}

#[derive(Valuable, Debug)]
struct Foo {
name: &'static str,
}

test_tuple! {
test_0 => 0, ();
test_1 => 1, (123,);
test_2 => 2, (123, "foo");
test_3 => 3, (123, "foo", "bar".to_string());
test_4 => 4, ("bar".to_string(), 123, "foo", Foo { name: "Foo" });
test_10 => 10, (
1,
"two",
3_u64,
4_f32,
"five".to_string(),
6,
7,
8,
Foo { name: "nine" },
10,
);
}

#[test]
fn test_dyn_impl() {
struct MyTuple;

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

fn visit(&self, visit: &mut dyn Visit) {
visit.visit_unnamed_fields(&[Value::I32(123), Value::String("hello world")]);
visit.visit_unnamed_fields(&[Value::String("j/k there is more")]);
}
}

impl Tuplable for MyTuple {
fn definition(&self) -> TupleDef {
TupleDef::new_dynamic((0, None))
}
}

let def = MyTuple.definition();
assert!(!def.is_unit());
assert!(def.is_dynamic());

assert_eq!(
format!("{:?}", MyTuple.as_value()),
format!("{:?}", (123, "hello world", "j/k there is more")),
);
}
34 changes: 0 additions & 34 deletions tests/tests/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,40 +248,6 @@ fn test_error() {
assert_value!(&'a dyn error::Error: Error, as_error, yes => error);
}

#[test]
fn test_unit() {
use Value::Unit;

struct VisitValue;

impl Visit for VisitValue {
fn visit_value(&mut self, val: Value<'_>) {
assert!(matches!(val, Unit));
}
}

// Visit the raw value once
assert_visit_call!(&());
let mut visit = VisitValue;
().visit(&mut visit);

let val = Value::from(());

// Visit the converted value
assert_visit_call!(&());
let mut visit = VisitValue;
val.visit(&mut visit);

// Test conversion
assert!(matches!(val, Unit));

// Test `as_value()`
assert!(matches!(Valuable::as_value(&()), Unit));

// Test clone()
assert!(matches!(val.clone(), Unit));
}

test_num! {
test_u8(as_u8, u8, U8);
test_u16(as_u16, u16, U16);
Expand Down
7 changes: 7 additions & 0 deletions valuable-serde/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,13 @@ where
}
_ => unreachable!(),
},
Value::Tuplable(t) => {
if t.definition().is_unit() {
serializer.serialize_unit()
} else {
unimplemented!()
}
}
#[cfg(feature = "std")]
Value::Path(p) => Serialize::serialize(p, serializer),
#[cfg(feature = "std")]
Expand Down
3 changes: 3 additions & 0 deletions valuable/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ pub use slice::Slice;
mod structable;
pub use structable::{StructDef, Structable};

mod tuplable;
pub use tuplable::{Tuplable, TupleDef};

mod valuable;
pub use crate::valuable::Valuable;

Expand Down
3 changes: 2 additions & 1 deletion valuable/src/structable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ impl<'a> StructDef<'a> {
/// Create a new [`StructDef::Dynamic`] instance.
///
/// This is used when the struct's fields may vary at runtime.
///
/// # Examples
///
/// ```
Expand Down Expand Up @@ -438,7 +439,7 @@ impl<'a> StructDef<'a> {
matches!(self, StructDef::Static { .. })
}

/// Returns `true` if the struct is [dynamically defined](StructDef::Static).
/// Returns `true` if the struct is [dynamically defined](StructDef::Dynamic).
///
/// # Examples
///
Expand Down
Loading

0 comments on commit b1e12a9

Please sign in to comment.