Skip to content

Commit

Permalink
chore: encapsulate all contexts
Browse files Browse the repository at this point in the history
  • Loading branch information
raklaptudirm committed Apr 23, 2024
1 parent ae2026d commit 7109ec7
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 5 deletions.
12 changes: 7 additions & 5 deletions uai/src/cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@ use std::fmt;
use std::sync::{Arc, Mutex};
use std::thread;

use crate::Context;

use super::{Flag, FlagValues};

/// Command represents a runnable UAI command. It contains all the metadata
/// needed to parse and verify a Command request from the GUI for a Command, and
/// to run that Command with the current context and the provided flag values.
/// `T` is the context type of the [Client], while `E` is the error type. `E`
/// must implement the [`RunError`] trait to be usable.
pub struct Command<T, E: RunError> {
pub struct Command<T: Send, E: RunError> {
/// run_fn is the function used to run this Command.
pub run_fn: RunFn<T, E>,
/// flags is the schema of the Flags this Command accepts.
Expand All @@ -38,19 +40,19 @@ impl<T: Send + 'static, E: RunError + 'static> Command<T, E> {
/// the error returned by the Command's execution, or [`Ok`] for parallel.
pub fn run(&self, context: &Arc<Mutex<T>>, flags: FlagValues) -> Result<(), E> {
// Clone values which might be moved by spawning a new thread.
let context = Arc::clone(context);
let context = Context::new(context, flags);
let func = self.run_fn;

if self.parallel {
// If the Command is supposed to be run in parallel, spawn a new
// thread and detach it for its execution. Syncing with the thread
// should be handled by the user using the context.
thread::spawn(move || func(context, flags));
thread::spawn(move || func(context));
return Ok(());
}

// Run the synchronous Command and return its error.
func(context, flags)
func(context)
}
}

Expand Down Expand Up @@ -115,7 +117,7 @@ impl<T: Send, E: RunError> Command<T, E> {
/// with the context (`Arc<Mutex<T>>`) and the flag values ([`FlagValues`]) whenever
/// the Command is to be executed. It returns a `Result<(), E>` where `E` implements
/// [`RunError`] and is the error type for the [Client].
pub type RunFn<T, E> = fn(Arc<Mutex<T>>, FlagValues) -> Result<(), E>;
pub type RunFn<T, E> = fn(Context<T>) -> Result<(), E>;

/// RunError is the interface which the Client uses to understand custom errors
/// returned by a Command. It allows the user to implement their own error types
Expand Down
31 changes: 31 additions & 0 deletions uai/src/context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use std::sync::{Arc, Mutex, MutexGuard};

use crate::FlagValues;

pub struct Context<T: Send> {
context: Arc<Mutex<T>>,
flags: FlagValues,
}

impl<T: Send> Context<T> {
pub fn new(context: &Arc<Mutex<T>>, flags: FlagValues) -> Context<T> {
let context = Arc::clone(context);
Context { context, flags }
}

pub fn lock(&self) -> MutexGuard<'_, T> {
self.context.lock().unwrap()
}

pub fn is_flag_set(&self, name: &str) -> bool {
self.flags.is_set(name)
}

pub fn get_single_flag(&self, name: &str) -> Option<String> {
self.flags.get_single(name)
}

pub fn get_array_flag(&self, name: &str) -> Option<Vec<String>> {
self.flags.get_array(name)
}
}
2 changes: 2 additions & 0 deletions uai/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ pub mod inbuilt;

mod client;
mod cmd;
mod context;
mod flag;
mod parameter;

pub use self::client::*;
pub use self::cmd::*;
pub use self::context::*;
pub use self::flag::*;
pub use self::parameter::*;

0 comments on commit 7109ec7

Please sign in to comment.