-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #4 from tinythings/isbm-checkbook-orphans
Implement module calls by entities
- Loading branch information
Showing
16 changed files
with
431 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod modfinder; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
use serde::{Deserialize, Serialize}; | ||
use std::{collections::HashMap, fmt::Display, path::PathBuf}; | ||
|
||
#[derive(Debug, Deserialize, Serialize, Clone)] | ||
pub struct ModCall { | ||
state: String, | ||
module: PathBuf, | ||
args: Vec<HashMap<String, String>>, | ||
opts: Vec<String>, | ||
} | ||
|
||
impl ModCall { | ||
/// Set state | ||
pub fn set_state(mut self, state: String) -> Self { | ||
self.state = state; | ||
self | ||
} | ||
|
||
/// Set resolved module physical path | ||
pub fn set_module(mut self, modpath: PathBuf) -> Self { | ||
self.module = modpath; | ||
self | ||
} | ||
|
||
/// Add a pair of kwargs | ||
pub fn add_kwargs(&mut self, kw: String, arg: String) -> &mut Self { | ||
self.args.push([(kw, arg)].into_iter().collect()); | ||
self | ||
} | ||
|
||
/// Add an option | ||
pub fn add_opt(&mut self, opt: String) -> &mut Self { | ||
self.opts.push(opt); | ||
self | ||
} | ||
|
||
pub fn run(&self) { | ||
log::debug!("run() of {}", self); | ||
} | ||
|
||
pub fn state(&self) -> String { | ||
self.state.to_owned() | ||
} | ||
|
||
/// Get state ref | ||
pub fn with_state(&self, state: String) -> bool { | ||
self.state == state | ||
} | ||
} | ||
|
||
impl Default for ModCall { | ||
fn default() -> Self { | ||
Self { state: "$".to_string(), module: PathBuf::default(), args: Default::default(), opts: Default::default() } | ||
} | ||
} | ||
|
||
impl Display for ModCall { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
write!(f, "ModCall - State: {}, Module: {:?}, Opts: {:?}, Args: {:?}", self.state, self.module, self.opts, self.args)?; | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,66 @@ | ||
use super::entities::Entity; | ||
use std::collections::HashMap; | ||
use super::relations::Relation; | ||
use serde_yaml::Value; | ||
use std::{collections::HashMap, fmt::Display}; | ||
|
||
pub struct Checkbook { | ||
entities: HashMap<String, Entity>, | ||
#[derive(Debug, Default)] | ||
pub struct CheckbookSection { | ||
id: String, | ||
relations: Vec<Relation>, | ||
} | ||
|
||
impl Checkbook { | ||
impl CheckbookSection { | ||
/// Initialise a checkbook. | ||
/// Entry is a list of relations needs to be examined. | ||
pub fn new(entry: Vec<String>) -> Self { | ||
Checkbook { entities: HashMap::new() }.load(entry) | ||
pub fn new(label: &Value, rel_ids: &Value, relations: &HashMap<String, Relation>) -> Option<Self> { | ||
let mut instance = CheckbookSection::default(); | ||
|
||
// No relations defined anyway | ||
if relations.is_empty() { | ||
return None; | ||
} | ||
|
||
// Check if there is at least one requested Id in the set of relations | ||
let mut orphans: Vec<String> = Vec::default(); | ||
if let Some(rel_ids) = rel_ids.as_sequence() { | ||
for rid in rel_ids.iter().map(|s| s.as_str().unwrap_or("").to_string()).collect::<Vec<String>>() { | ||
if let Some(rel) = relations.get(&rid) { | ||
instance.relations.push(rel.to_owned()); | ||
} else { | ||
orphans.push(rid); | ||
} | ||
} | ||
instance.id = label.as_str().unwrap_or("").to_string(); | ||
} | ||
|
||
// Checks | ||
if instance.id.is_empty() { | ||
log::error!("Checkbook section should have an Id"); | ||
return None; | ||
} | ||
|
||
// Feedback only | ||
if !orphans.is_empty() { | ||
log::warn!("Checkbook section \"{}\" has {} bogus relations: {}", instance.id, orphans.len(), orphans.join(", ")); | ||
} | ||
|
||
// Discard invalid section | ||
if instance.relations.is_empty() { | ||
log::error!("Checkbook \"{}\" has no valid relations assotiated", instance.id); | ||
return None; | ||
} | ||
|
||
Some(instance) | ||
} | ||
|
||
/// Get Id of the checkbook section | ||
pub fn id(&self) -> String { | ||
self.id.to_owned() | ||
} | ||
} | ||
|
||
fn load(self, entry: Vec<String>) -> Self { | ||
self | ||
impl Display for CheckbookSection { | ||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
write!(f, "<CheckbookSection - Id: {}, Relations: {:?}>", self.id, self.relations)?; | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
use crate::SysinspectError; | ||
use serde::{Deserialize, Serialize}; | ||
use serde_yaml::Value; | ||
use std::path::PathBuf; | ||
|
||
#[derive(Debug, Serialize, Deserialize, Clone, Default)] | ||
pub struct Config { | ||
modules: PathBuf, | ||
} | ||
|
||
impl Config { | ||
pub fn new(obj: &Value) -> Result<Self, SysinspectError> { | ||
if let Ok(instance) = serde_yaml::from_value::<Config>(obj.to_owned()) { | ||
return Ok(instance); | ||
} | ||
|
||
Err(SysinspectError::ModelDSLError("Unable to parse configuration".to_string())) | ||
} | ||
|
||
/// Get module from the namespace | ||
pub fn get_module(&self, namespace: &str) -> Result<PathBuf, SysinspectError> { | ||
// Fool-proof cleanup, likely a bad idea | ||
let modpath = self.modules.join( | ||
namespace | ||
.trim_start_matches('.') | ||
.trim_end_matches('.') | ||
.trim() | ||
.split('.') | ||
.map(|s| s.to_string()) | ||
.collect::<Vec<String>>() | ||
.join("/"), | ||
); | ||
|
||
if !modpath.exists() { | ||
return Err(SysinspectError::ModuleError(format!("Module \"{}\" was not found", namespace))); | ||
} | ||
|
||
Ok(modpath) | ||
} | ||
} |
Oops, something went wrong.