diff --git a/README.md b/README.md index d904049..c7cbd53 100644 --- a/README.md +++ b/README.md @@ -202,8 +202,8 @@ fn plus_two(counter: Update, tgt: Target, Path(name): Pa // A compound job returns a list of tasks that need to be executed // to achieve a certain goal vec![ - plus_one.into_task(Context::new().with_target(*tgt).with_arg("name", &name)), - plus_one.into_task(Context::new().with_target(*tgt).with_arg("name", &name)), + plus_one.into_task(Context::new().target(*tgt).arg("name", &name)), + plus_one.into_task(Context::new().target(*tgt).arg("name", &name)), ] } diff --git a/src/extract/view.rs b/src/extract/view.rs index 5b847b0..b336996 100644 --- a/src/extract/view.rs +++ b/src/extract/view.rs @@ -315,7 +315,7 @@ mod tests { let system = System::from(state); let mut view: View = - View::from_system(&system, &Context::default().with_path("/numbers/one")).unwrap(); + View::from_system(&system, &Context::new().path("/numbers/one")).unwrap(); assert_eq!(view.as_ref(), Some(&1)); @@ -346,14 +346,13 @@ mod tests { assert!(View::::from_system( &system, - &Context::default().with_path("/numbers/one/two"), - ) - .is_err()); - assert!(View::::from_system( - &system, - &Context::default().with_path("/none/two"), + &Context::default().path("/numbers/one/two"), ) .is_err()); + assert!( + View::::from_system(&system, &Context::default().path("/none/two"),) + .is_err() + ); } #[test] @@ -367,7 +366,7 @@ mod tests { let system = System::from(state); let mut view: View = - View::from_system(&system, &Context::default().with_path("/numbers/three")).unwrap(); + View::from_system(&system, &Context::default().path("/numbers/three")).unwrap(); assert_eq!(view.as_ref(), None); @@ -395,7 +394,7 @@ mod tests { let system = System::from(state); let mut view: Create = - Create::from_system(&system, &Context::default().with_path("/numbers/three")).unwrap(); + Create::from_system(&system, &Context::default().path("/numbers/three")).unwrap(); *view = 3; // Get the list changes to the view @@ -421,7 +420,7 @@ mod tests { assert!(Create::::from_system( &system, - &Context::default().with_path("/none/three") + &Context::default().path("/none/three") ) .is_err()); } @@ -437,7 +436,7 @@ mod tests { let system = System::from(state); let mut view: Update = - Update::from_system(&system, &Context::default().with_path("/numbers/two")).unwrap(); + Update::from_system(&system, &Context::default().path("/numbers/two")).unwrap(); *view = 3; // Get the list changes to the view @@ -463,12 +462,12 @@ mod tests { assert!(Update::::from_system( &system, - &Context::default().with_path("/numbers/three") + &Context::default().path("/numbers/three") ) .is_err()); assert!(Update::::from_system( &system, - &Context::default().with_path("/none/three") + &Context::default().path("/none/three") ) .is_err()); } @@ -484,7 +483,7 @@ mod tests { let system = System::from(state); let mut view: View = - View::from_system(&system, &Context::default().with_path("/numbers/three")).unwrap(); + View::from_system(&system, &Context::default().path("/numbers/three")).unwrap(); assert_eq!(view.as_ref(), None); @@ -513,7 +512,7 @@ mod tests { let system = System::from(state); let mut view: View = - View::from_system(&system, &Context::default().with_path("/numbers/one")).unwrap(); + View::from_system(&system, &Context::default().path("/numbers/one")).unwrap(); // Delete the value view.delete(); @@ -538,7 +537,7 @@ mod tests { let system = System::from(state); let mut view: View = - View::from_system(&system, &Context::default().with_path("/numbers/1")).unwrap(); + View::from_system(&system, &Context::default().path("/numbers/1")).unwrap(); assert_eq!(view.as_ref(), Some(&"two".to_string())); @@ -565,7 +564,7 @@ mod tests { let system = System::from(state); let mut view: View = - View::from_system(&system, &Context::default().with_path("/numbers/2")).unwrap(); + View::from_system(&system, &Context::default().path("/numbers/2")).unwrap(); assert_eq!(view.as_ref(), None); view.create("three".to_string()); @@ -590,7 +589,7 @@ mod tests { let system = System::from(state); let mut view: View = - View::from_system(&system, &Context::default().with_path("/numbers/1")).unwrap(); + View::from_system(&system, &Context::default().path("/numbers/1")).unwrap(); // Remove the second element view.delete(); @@ -617,7 +616,7 @@ mod tests { let system = System::from(state); let mut view: View = - View::from_system(&system, &Context::default().with_path("/numbers/2")).unwrap(); + View::from_system(&system, &Context::default().path("/numbers/2")).unwrap(); // Remove the third element view.delete(); diff --git a/src/path.rs b/src/path.rs index 2a04bb7..ae53dfc 100644 --- a/src/path.rs +++ b/src/path.rs @@ -39,7 +39,13 @@ impl AsRef for Path { pub(crate) struct PathArgs(pub Vec<(Arc, String)>); impl PathArgs { - pub fn new(params: matchit::Params) -> Self { + pub fn new() -> Self { + PathArgs(Vec::new()) + } +} + +impl<'k, 'v> From> for PathArgs { + fn from(params: matchit::Params) -> PathArgs { let params: Vec<(Arc, String)> = params .iter() .map(|(k, v)| (Arc::from(k), String::from(v))) diff --git a/src/task/context.rs b/src/task/context.rs index 9559e9a..a0b08f6 100644 --- a/src/task/context.rs +++ b/src/task/context.rs @@ -1,8 +1,11 @@ -use crate::path::Path; +use std::sync::Arc; + +use crate::path::{Path, PathArgs}; pub struct Context { - pub target: Option, - pub path: Path, + pub(crate) target: Option, + pub(crate) path: Path, + pub(crate) args: PathArgs, } impl Default for Context { @@ -10,24 +13,45 @@ impl Default for Context { Context { target: None, path: Path::default(), + args: PathArgs::new(), } } } impl Context { - pub fn from_target(target: S) -> Self { + pub fn new() -> Self { + Self::default() + } + + pub fn target(self, target: S) -> Self { Self { target: Some(target), - path: Path::default(), + path: self.path, + args: self.args, } } - pub fn with_path(self, path: &'static str) -> Self { + // This will be used by the planner + #[allow(dead_code)] + pub(crate) fn path(self, path: &'static str) -> Self { Self { target: self.target, path: Path::from_static(path), + args: self.args, } } + + pub fn arg(self, key: impl AsRef, value: impl Into) -> Self { + let Self { + target, + path, + mut args, + } = self; + + args.0.push((Arc::from(key.as_ref()), value.into())); + + Self { target, path, args } + } } impl Clone for Context { @@ -35,6 +59,7 @@ impl Clone for Context { Context { target: self.target.clone(), path: self.path.clone(), + args: self.args.clone(), } } } diff --git a/src/task/domain.rs b/src/task/domain.rs index f8425c0..e8fdffb 100644 --- a/src/task/domain.rs +++ b/src/task/domain.rs @@ -120,7 +120,7 @@ impl Domain { .at(path) .map(|matched| { ( - PathArgs::new(matched.params), + PathArgs::from(matched.params), matched .value .iter() @@ -156,8 +156,8 @@ mod tests { } vec![ - plus_one.into_task(Context::from_target(*tgt)), - plus_one.into_task(Context::from_target(*tgt)), + plus_one.into_task(Context::new().target(*tgt)), + plus_one.into_task(Context::new().target(*tgt)), ] } diff --git a/src/task/mod.rs b/src/task/mod.rs index ed6397a..646ccfd 100644 --- a/src/task/mod.rs +++ b/src/task/mod.rs @@ -181,8 +181,8 @@ mod tests { } vec![ - plus_one.into_task(Context::from_target(*tgt)), - plus_one.into_task(Context::from_target(*tgt)), + plus_one.into_task(Context::new().target(*tgt)), + plus_one.into_task(Context::new().target(*tgt)), ] } @@ -209,7 +209,7 @@ mod tests { fn it_allows_to_dry_run_tasks() { let system = System::from(0); let job = plus_one.into_job(); - let task = job.into_task(Context::from_target(1)); + let task = job.into_task(Context::new().target(1)); // Get the list of changes that the action performs let changes = task.dry_run(&system).unwrap(); @@ -226,7 +226,7 @@ mod tests { fn it_allows_to_dry_run_composite_tasks() { let system = System::from(0); let job = plus_two.into_job(); - let task = job.into_task(Context::from_target(2)); + let task = job.into_task(Context::new().target(2)); // Get the list of changes that the method performs let changes = task.dry_run(&system).unwrap(); @@ -243,7 +243,7 @@ mod tests { #[tokio::test] async fn it_allows_to_run_composite_tasks() { let mut system = System::from(0); - let task = plus_two.into_task(Context::from_target(2)); + let task = plus_two.into_task(Context::new().target(2)); // Run the action task.run(&mut system).await.unwrap(); @@ -257,7 +257,7 @@ mod tests { #[tokio::test] async fn it_runs_async_actions() { let mut system = System::from(0); - let task = plus_one.into_task(Context::from_target(1)); + let task = plus_one.into_task(Context::new().target(1)); // Run the action task.run(&mut system).await.unwrap(); @@ -272,7 +272,7 @@ mod tests { async fn it_allows_extending_actions_with_effect() { let mut system = System::from(0); let job = plus_one_async.into_job(); - let task = job.into_task(Context::from_target(1)); + let task = job.into_task(Context::new().target(1)); // Run the action task.run(&mut system).await.unwrap(); @@ -285,7 +285,7 @@ mod tests { #[tokio::test] async fn it_allows_actions_returning_errors() { let mut system = System::from(1); - let task = plus_one_async.into_task(Context::from_target(1)); + let task = plus_one_async.into_task(Context::new().target(1)); let res = task.run(&mut system).await; assert!(res.is_err()); @@ -319,10 +319,11 @@ mod tests { let mut system = System::from(state); let task = update_counter.into_job(); let action = task.into_task( - Context::from_target(State { - counters: [("a".to_string(), 2), ("b".to_string(), 1)].into(), - }) - .with_path("/counters/a"), + Context::new() + .target(State { + counters: [("a".to_string(), 2), ("b".to_string(), 1)].into(), + }) + .path("/counters/a"), ); // Run the action diff --git a/tests/library_test.rs b/tests/library_test.rs index 013e15f..bcec474 100644 --- a/tests/library_test.rs +++ b/tests/library_test.rs @@ -20,7 +20,7 @@ fn my_task_effect(mut counter: Update, tgt: Target) -> Effect