From 5353ccc0015a53ffad72f7d87f9940ae811be9ff Mon Sep 17 00:00:00 2001 From: cksac Date: Wed, 13 Mar 2024 08:18:53 +0800 Subject: [PATCH] update either faker --- README.md | 13 +++++++++++++ dummy_derive/src/lib.rs | 7 +++++++ fake/examples/derive.rs | 11 +++++++++++ fake/examples/utils.rs | 7 +++++-- fake/src/utils.rs | 35 +++++++++++++++++++++++++++-------- 5 files changed, 63 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 39ef0e9..a2e7636 100644 --- a/README.md +++ b/README.md @@ -312,6 +312,19 @@ NegativeBigDecimal(); NoBigDecimalPoints(); ``` +## Utils +### Either +```rust +use fake::faker::phone_number::en::{CellNumber, PhoneNumber}; +use fake::{utils::{either, WrappedVal}, Dummy, Fake, Faker}; + +#[derive(Debug, Dummy)] +struct Foo { + #[dummy(faker = "either(PhoneNumber(), CellNumber())", wrapper = "WrappedVal")] + phone_number: String, +} +``` + # LICENSE This project is licensed under either of diff --git a/dummy_derive/src/lib.rs b/dummy_derive/src/lib.rs index 128aac8..11cea29 100644 --- a/dummy_derive/src/lib.rs +++ b/dummy_derive/src/lib.rs @@ -38,6 +38,8 @@ struct DummyField { default: bool, #[darling(default)] from: Option, + #[darling(default)] + wrapper: Option, } #[derive(Debug, FromDeriveInput)] @@ -222,6 +224,11 @@ fn expose_field(f: &DummyField) -> proc_macro2::TokenStream { quote! { std::convert::Into::<#field_ty>::into(::fake::Fake::fake_with_rng::<#from_ty, _>(&(#faker), rng)) } + } else if let Some(ref wrapper) = f.wrapper { + let wrapper_ty = syn::parse_str::(wrapper).unwrap(); + quote! { + ::fake::utils::IntoInner::into_inner(::fake::Fake::fake_with_rng::<#wrapper_ty<#field_ty>, _>(&(#faker), rng)) + } } else { quote! { ::fake::Fake::fake_with_rng::<#field_ty, _>(&(#faker), rng) diff --git a/fake/examples/derive.rs b/fake/examples/derive.rs index a5ae659..187ca23 100644 --- a/fake/examples/derive.rs +++ b/fake/examples/derive.rs @@ -2,6 +2,7 @@ use fake::decimal::*; use fake::faker::boolean::en::*; use fake::faker::company::en::*; use fake::faker::name::en::*; +use fake::utils::{either, WrappedVal}; use fake::uuid::UUIDv4; use fake::Dummy; use fake::{Fake, Faker}; @@ -104,6 +105,13 @@ struct MyStruct { field: Vec, } +#[allow(dead_code)] +#[derive(Debug, Dummy)] +struct FakerWrapperStruct { + #[dummy(faker = "either(Buzzword(), CompanyName())", wrapper = "WrappedVal")] + pub val: String, +} + fn main() { let order: Order = Faker.fake(); println!("{:#?}", order); @@ -134,4 +142,7 @@ fn main() { let v: MyStruct = Faker.fake(); println!("{:#?}", v); + + let v: FakerWrapperStruct = Faker.fake(); + println!("{:#?}", v); } diff --git a/fake/examples/utils.rs b/fake/examples/utils.rs index 294108c..811737b 100644 --- a/fake/examples/utils.rs +++ b/fake/examples/utils.rs @@ -1,9 +1,12 @@ use fake::faker::phone_number::en::{CellNumber, PhoneNumber}; -use fake::{utils::either, Dummy, Fake, Faker}; +use fake::{ + utils::{either, WrappedVal}, + Dummy, Fake, Faker, +}; #[derive(Debug, Dummy)] struct Foo { - #[dummy(faker = "either(PhoneNumber(), CellNumber())")] + #[dummy(faker = "either(PhoneNumber(), CellNumber())", wrapper = "WrappedVal")] phone_number: String, } diff --git a/fake/src/utils.rs b/fake/src/utils.rs index d121ae8..9b6e81b 100644 --- a/fake/src/utils.rs +++ b/fake/src/utils.rs @@ -1,26 +1,45 @@ use crate::{Dummy, Fake, Faker}; use rand::Rng; -pub struct Either { +pub trait IntoInner { + type Target; + fn into_inner(self) -> Self::Target; +} + +pub struct EitherFaker { pub a: A, pub b: B, } -impl Dummy> for String +pub struct WrappedVal(pub T); +impl WrappedVal { + pub fn new(val: T) -> Self { + Self(val) + } +} + +impl IntoInner for WrappedVal { + type Target = T; + fn into_inner(self) -> Self::Target { + self.0 + } +} + +impl Dummy> for WrappedVal where - String: Dummy + Dummy, + T: Dummy + Dummy, { - fn dummy_with_rng(config: &Either, rng: &mut R) -> Self { + fn dummy_with_rng(config: &EitherFaker, rng: &mut R) -> Self { if Faker.fake_with_rng(rng) { - config.a.fake_with_rng(rng) + WrappedVal::new(config.a.fake_with_rng(rng)) } else { - config.b.fake_with_rng(rng) + WrappedVal::new(config.b.fake_with_rng(rng)) } } } -pub fn either(a: A, b: B) -> Either { - Either { a, b } +pub fn either(a: A, b: B) -> EitherFaker { + EitherFaker { a, b } } #[cfg(feature = "always-true-rng")]