Skip to content

Commit

Permalink
Smash a couple of thinkos and wrongdoings
Browse files Browse the repository at this point in the history
  • Loading branch information
vrurg committed Nov 26, 2024
1 parent b36074f commit 1962c89
Show file tree
Hide file tree
Showing 10 changed files with 243 additions and 69 deletions.
72 changes: 59 additions & 13 deletions fieldx/tests/async_fallible.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,79 @@
use fieldx::fxstruct;
use std::sync::Arc;

#[fxstruct(mode(async), fallible(off, error(String)))]
struct Foo {
struct Foo<const FAIL: bool = false> {
#[fieldx(lazy, fallible)]
never_ok: i32,
ok: i32,

#[fieldx(lazy, fallible, get_mut)]
#[fieldx(lazy, fallible, get(copy), get_mut, set)]
writable: u32,

#[fieldx(lazy, fallible, get(clone))]
shared: Arc<String>,
}

impl Foo {
async fn build_never_ok(&self) -> Result<i32, String> {
Err("will never be there".to_string())
impl<const FAIL: bool> Foo<FAIL> {
async fn build_ok(&self) -> Result<i32, String> {
if FAIL {
Err("will never be there".to_string())
}
else {
Ok(-42)
}
}

async fn build_writable(&self) -> Result<u32, String> {
Ok(12)
if FAIL {
Err("no value".to_string())
}
else {
Ok(12)
}
}

async fn build_shared(&self) -> Result<Arc<String>, String> {
if FAIL {
Err("this is a failed outcome".to_string())
}
else {
Ok(Arc::new("shared".to_string()))
}
}
}

#[tokio::test]
async fn fallible() -> Result<(), Box<dyn std::error::Error>> {
let foo = Foo::new();
assert!(foo.never_ok().await.is_err());
assert_eq!(*foo.never_ok().await.unwrap_err(), String::from("will never be there"));
async fn fallible_ok() -> Result<(), Box<dyn std::error::Error>> {
let foo = Foo::<false>::new();

assert!(*foo.ok().await? == -42);

assert_eq!(*foo.writable().await?, 12);
assert_eq!(foo.writable().await?, 12);
*foo.writable_mut().await? = 42;
assert_eq!(*foo.writable().await?, 42);
assert_eq!(foo.writable().await?, 42);

assert_eq!(*foo.shared().await?, "shared".to_string());

Ok(())
}

#[tokio::test]
async fn fallible_error() -> Result<(), Box<dyn std::error::Error>> {
let foo = Foo::<true>::new();

assert!(foo.ok().await.is_err());
assert_eq!(*foo.ok().await.unwrap_err(), String::from("will never be there"));

assert!(foo.writable().await.is_err());
assert_eq!(foo.writable().await.unwrap_err(), "no value".to_string());
foo.set_writable(42).await;
assert_eq!(foo.writable().await?, 42);

assert!(foo.shared().await.is_err());
assert_eq!(
*foo.shared().await.unwrap_err(),
String::from("this is a failed outcome")
);

Ok(())
}
69 changes: 56 additions & 13 deletions fieldx/tests/plain_fallible.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,76 @@
use fieldx::fxstruct;
use std::rc::Rc;

#[fxstruct(mode(plain), fallible(off, error(String)))]
struct Foo {
struct Foo<const FAIL: bool = false> {
#[fieldx(lazy, fallible)]
never_ok: i32,
ok: i32,

#[fieldx(lazy, fallible, get_mut)]
#[fieldx(lazy, fallible, get(copy), get_mut, set)]
writable: u32,

#[fieldx(lazy, fallible, get(clone))]
shared: Rc<String>,
}

impl Foo {
fn build_never_ok(&self) -> Result<i32, String> {
Err("will never be there".to_string())
impl<const FAIL: bool> Foo<FAIL> {
fn build_ok(&self) -> Result<i32, String> {
if FAIL {
Err("will never be there".to_string())
}
else {
Ok(-42)
}
}

fn build_writable(&self) -> Result<u32, String> {
Ok(12)
if FAIL {
Err("no value".to_string())
}
else {
Ok(12)
}
}

fn build_shared(&self) -> Result<Rc<String>, String> {
if FAIL {
Err("this is a failed outcome".to_string())
}
else {
Ok(Rc::new("shared".to_string()))
}
}
}

#[test]
fn fallible() -> Result<(), Box<dyn std::error::Error>> {
let mut foo = Foo::new();
assert!(foo.never_ok().is_err());
assert_eq!(*foo.never_ok().unwrap_err(), String::from("will never be there"));
fn fallible_ok() -> Result<(), Box<dyn std::error::Error>> {
let mut foo = Foo::<false>::new();

assert!(*foo.ok()? == -42);

assert_eq!(*foo.writable()?, 12);
assert_eq!(foo.writable()?, 12);
*foo.writable_mut()? = 42;
assert_eq!(*foo.writable()?, 42);
assert_eq!(foo.writable()?, 42);

assert_eq!(*foo.shared()?, "shared".to_string());

Ok(())
}

#[test]
fn fallible_error() -> Result<(), Box<dyn std::error::Error>> {
let mut foo = Foo::<true>::new();

assert!(foo.ok().is_err());
assert_eq!(*foo.ok().unwrap_err(), String::from("will never be there"));

assert!(foo.writable().is_err());
assert_eq!(foo.writable().unwrap_err(), "no value".to_string());
foo.set_writable(42);
assert_eq!(foo.writable()?, 42);

assert!(foo.shared().is_err());
assert_eq!(*foo.shared().unwrap_err(), String::from("this is a failed outcome"));

Ok(())
}
69 changes: 56 additions & 13 deletions fieldx/tests/sync_fallible.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,76 @@
use fieldx::fxstruct;
use std::sync::Arc;

#[fxstruct(mode(sync), fallible(off, error(String)))]
struct Foo {
struct Foo<const FAIL: bool = false> {
#[fieldx(lazy, fallible)]
never_ok: i32,
ok: i32,

#[fieldx(lazy, fallible, get_mut)]
#[fieldx(lazy, fallible, get(copy), get_mut, set)]
writable: u32,

#[fieldx(lazy, fallible, get(clone))]
shared: Arc<String>,
}

impl Foo {
fn build_never_ok(&self) -> Result<i32, String> {
Err("will never be there".to_string())
impl<const FAIL: bool> Foo<FAIL> {
fn build_ok(&self) -> Result<i32, String> {
if FAIL {
Err("will never be there".to_string())
}
else {
Ok(-42)
}
}

fn build_writable(&self) -> Result<u32, String> {
Ok(12)
if FAIL {
Err("no value".to_string())
}
else {
Ok(12)
}
}

fn build_shared(&self) -> Result<Arc<String>, String> {
if FAIL {
Err("this is a failed outcome".to_string())
}
else {
Ok(Arc::new("shared".to_string()))
}
}
}

#[test]
fn fallible() -> Result<(), Box<dyn std::error::Error>> {
let foo = Foo::new();
assert!(foo.never_ok().is_err());
assert_eq!(*foo.never_ok().unwrap_err(), String::from("will never be there"));
fn fallible_ok() -> Result<(), Box<dyn std::error::Error>> {
let foo = Foo::<false>::new();

assert!(*foo.ok()? == -42);

assert_eq!(*foo.writable()?, 12);
assert_eq!(foo.writable()?, 12);
*foo.writable_mut()? = 42;
assert_eq!(*foo.writable()?, 42);
assert_eq!(foo.writable()?, 42);

assert_eq!(*foo.shared()?, "shared".to_string());

Ok(())
}

#[test]
fn fallible_error() -> Result<(), Box<dyn std::error::Error>> {
let foo = Foo::<true>::new();

assert!(foo.ok().is_err());
assert_eq!(*foo.ok().unwrap_err(), String::from("will never be there"));

assert!(foo.writable().is_err());
assert_eq!(foo.writable().unwrap_err(), "no value".to_string());
foo.set_writable(42);
assert_eq!(foo.writable()?, 42);

assert!(foo.shared().is_err());
assert_eq!(*foo.shared().unwrap_err(), String::from("this is a failed outcome"));

Ok(())
}
12 changes: 5 additions & 7 deletions fieldx_derive/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -279,12 +279,11 @@ impl FXRewriter {

let defaults = ctx.defaults_combined();
let ident = ctx.input().ident();
let generics = ctx.input().generics();
let where_clause = &generics.where_clause;
let (impl_generics, type_generics, where_clause) = ctx.input().generics().split_for_impl();

if !defaults.is_empty() {
quote! [
impl #generics Default for #ident #generics #where_clause {
impl #impl_generics Default for #ident #type_generics #where_clause {
fn default() -> Self {
Self { #defaults }
}
Expand Down Expand Up @@ -476,8 +475,7 @@ impl FXRewriter {
let fields = ctx.struct_fields();
let default = self.default_impl();
let builder_struct = self.builder_struct();
let where_clause = &generics.where_clause;
let generic_params = ctx.struct_generic_params();
let (impl_generics, type_generics, where_clause) = generics.split_for_impl();

let copyables = ctx.copyable_types();
let copyable_validation = if !copyables.is_empty() {
Expand Down Expand Up @@ -505,10 +503,10 @@ impl FXRewriter {
#( #fields ),*
}

impl #generics FXStruct for #ident #generic_params #where_clause {}
impl #impl_generics FXStruct for #ident #type_generics #where_clause {}

#attributes_impl
impl #generics #ident #generics #where_clause {
impl #impl_generics #ident #type_generics #where_clause {
#methods
#copyable_validation
}
Expand Down
6 changes: 3 additions & 3 deletions fieldx_derive/src/codegen/plain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,12 @@ impl FXCodeGenContextual for FXCodeGenPlain {
if fctx.is_lazy() {
let lazy_init = self.field_lazy_initializer(fctx, None)?;
let ty = self.fallible_return_type(fctx, quote_spanned! {span=> #opt_ref #ty_tok})?;
let shortcut = fctx.fallible_shortcut();
let ret = fctx.fallible_ok_return(quote_spanned! {span=> #deref #lazy_init #shortcut #meth });

quote_spanned![span=>
#attributes_fn
#vis_tok fn #accessor_name(&self) -> #ty {
#deref #lazy_init #meth
}
#vis_tok fn #accessor_name(&self) -> #ty { #ret }
]
}
else {
Expand Down
Loading

0 comments on commit 1962c89

Please sign in to comment.