Skip to content

Commit

Permalink
Adds context to generate AutoGeneratedVariable values
Browse files Browse the repository at this point in the history
  • Loading branch information
cuducos committed Sep 18, 2023
1 parent b73f22f commit 381874d
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 40 deletions.
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anyhow = "1.0.71"
rand = "0.8.5"
58 changes: 45 additions & 13 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,59 @@
use crate::model::{Block, Comment, SimpleVariable, Variable};
use std::env::args;
use std::io::{stdout, BufWriter};

use anyhow::Result;

use crate::model::{
AutoGeneratedVariable, Block, Comment, SimpleVariable, VariableWithDefaultValue,
VariableWithRandomValue, Variables,
};

mod model;

fn main() {
fn main() -> Result<()> {
if let Some(path) = args().nth(1) {
let out = BufWriter::new(stdout());
let mut parser = Parser::new(out);

Check failure on line 16 in src/main.rs

View workflow job for this annotation

GitHub Actions / test-rs

failed to resolve: use of undeclared type `Parser`

Check failure on line 16 in src/main.rs

View workflow job for this annotation

GitHub Actions / test-rs

failed to resolve: use of undeclared type `Parser`
parser.parse(path)?;
return Ok(());
}

let title = Comment {
contents: "42".to_string(),
};
let description = Some(Comment {
contents: "Fourty-two".to_string(),
});
let variable1 = Box::new(SimpleVariable {
let variable1 = Variables::Simple(SimpleVariable {
name: "ANSWER".to_string(),
input: "42".to_string(),
}) as Box<dyn Variable>;
let variable2 = Box::new(SimpleVariable {
});
let variable2 = Variables::Simple(SimpleVariable {
name: "AS_TEXT".to_string(),
input: "fourty two".to_string(),
}) as Box<dyn Variable>;
let variables = vec![variable1, variable2];
let block = Block {
title,
description,
variables,
};
println!("{}", block)
});
let variable3 = Variables::DefaultValue(VariableWithDefaultValue {
name: "DEFAULT_VALUE_ONE".to_string(),
input: "".to_string(),
default: "default".to_string(),
});
let variable4 = Variables::DefaultValue(VariableWithDefaultValue {
name: "DEFAULT_VALUE_ONE".to_string(),
input: "custom".to_string(),
default: "default".to_string(),
});
let variable5 = Variables::Random(VariableWithRandomValue {
name: "SECRET_KEY".to_string(),
length: None,
});
let variable6 = Variables::AutoGenerated(AutoGeneratedVariable::new(
"AUTO_GENERATED".to_string(),
"{ANSWER}-{DEFAULT_VALUE_ONE}".to_string(),
));
let variables = vec![
variable1, variable2, variable3, variable4, variable5, variable6,
];
let block = Block::new(title, description, variables);
println!("{block}");
Ok(())
}
125 changes: 98 additions & 27 deletions src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,25 +40,43 @@ impl Variable for SimpleVariable {
pub struct VariableWithDefaultValue {
pub name: String,
pub default: String,
pub input: Option<String>,
pub input: String,
}

impl Variable for VariableWithDefaultValue {
fn key(&self) -> String {
self.name.to_string()
}
fn value(&self) -> String {
match &self.input {
Some(value) => value.to_string(),
None => self.default.to_string(),
if self.input.is_empty() {
self.default.to_string()
} else {
self.input.to_string()
}
}
}

pub struct AutoGeneratedVariable {
pub name: String,
pub pattern: String,
pub settings: HashMap<&'static str, &'static str>,

context: HashMap<String, String>,
}

impl AutoGeneratedVariable {
pub fn new(name: String, pattern: String) -> Self {
Self {
name,
pattern,
context: HashMap::new(),
}
}

pub fn load_context(&mut self, ctx: &HashMap<String, String>) {
for (k, v) in ctx.iter() {
self.context.insert(k.to_string(), v.to_string());
}
}
}

impl Variable for AutoGeneratedVariable {
Expand All @@ -67,9 +85,9 @@ impl Variable for AutoGeneratedVariable {
}
fn value(&self) -> String {
let mut value: String = self.pattern.to_string();
for (k, v) in self.settings.iter() {
for (k, v) in self.context.iter() {
let key = format!("{{{}}}", *k);
value = value.replace(&key, *v);
value = value.replace(&key, v);
}
value
}
Expand Down Expand Up @@ -100,10 +118,54 @@ impl Variable for VariableWithRandomValue {
}
}

pub enum Variables {
Simple(SimpleVariable),
DefaultValue(VariableWithDefaultValue),
AutoGenerated(AutoGeneratedVariable),
Random(VariableWithRandomValue),
}

pub struct Block {
pub title: Comment,
pub description: Option<Comment>,
pub variables: Vec<Box<dyn Variable>>,
pub variables: Vec<Variables>,

context: HashMap<String, String>,
}

impl Block {
pub fn new(title: Comment, description: Option<Comment>, variables: Vec<Variables>) -> Self {
let context: HashMap<String, String> = HashMap::new();
let has_auto_generated_variables = variables
.iter()
.any(|v| matches!(v, Variables::AutoGenerated(_)));

let mut block = Self {
title,
description,
variables,
context,
};

if has_auto_generated_variables {
for variable in &block.variables {
match variable {
Variables::Simple(var) => block.context.insert(var.key(), var.value()),
Variables::DefaultValue(var) => block.context.insert(var.key(), var.value()),
Variables::AutoGenerated(_) => None,
Variables::Random(var) => block.context.insert(var.key(), var.value()),
};
}

for variable in &mut block.variables {
if let Variables::AutoGenerated(var) = variable {
var.load_context(&block.context);
}
}
}

block
}
}

impl fmt::Display for Block {
Expand All @@ -113,9 +175,16 @@ impl fmt::Display for Block {
Some(desc) => lines.push(desc.to_string()),
None => (),
}

for variable in &self.variables {
lines.push(variable.to_string());
match variable {
Variables::Simple(var) => lines.push(var.to_string()),
Variables::DefaultValue(var) => lines.push(var.to_string()),
Variables::AutoGenerated(var) => lines.push(var.to_string()),
Variables::Random(var) => lines.push(var.to_string()),
}
}

write!(f, "{}", lines.join("\n"))
}
}
Expand Down Expand Up @@ -146,7 +215,7 @@ mod tests {
let line = VariableWithDefaultValue {
name: "ANSWER".to_string(),
default: "42".to_string(),
input: None,
input: "".to_string(),
};
assert_eq!(line.to_string(), "ANSWER=42")
}
Expand All @@ -156,21 +225,27 @@ mod tests {
let line = VariableWithDefaultValue {
name: "ANSWER".to_string(),
default: "42".to_string(),
input: Some("Fourty-two".to_string()),
input: "Fourty-two".to_string(),
};
assert_eq!(line.to_string(), "ANSWER=Fourty-two")
}

#[test]
fn test_auto_generated_variable() {
let mut settings = HashMap::new();
settings.insert("first", "Fourty");
settings.insert("second", "two");
let line = AutoGeneratedVariable {
name: "ANSWER".to_string(),
pattern: "{first}-{second}".to_string(),
settings,
let mut line =
AutoGeneratedVariable::new("ANSWER".to_string(), "{first}-{second}".to_string());
let first = SimpleVariable {
name: "first".to_string(),
input: "Fourty".to_string(),
};
let second = SimpleVariable {
name: "second".to_string(),
input: "two".to_string(),
};
let mut ctx = HashMap::new();
ctx.insert(first.key(), first.value());
ctx.insert(second.key(), second.value());
line.load_context(&ctx);
assert_eq!(line.to_string(), "ANSWER=Fourty-two")
}

Expand Down Expand Up @@ -209,20 +284,16 @@ mod tests {
let description = Some(Comment {
contents: "Fourty-two".to_string(),
});
let variable1 = Box::new(SimpleVariable {
let variable1 = Variables::Simple(SimpleVariable {
name: "ANSWER".to_string(),
input: "42".to_string(),
}) as Box<dyn Variable>;
let variable2 = Box::new(SimpleVariable {
});
let variable2 = Variables::Simple(SimpleVariable {
name: "AS_TEXT".to_string(),
input: "fourty two".to_string(),
}) as Box<dyn Variable>;
});
let variables = vec![variable1, variable2];
let block = Block {
title,
description,
variables,
};
let block = Block::new(title, description, variables);
let got = block.to_string();
assert_eq!(got, "# 42\n# Fourty-two\nANSWER=42\nAS_TEXT=fourty two")
}
Expand Down

0 comments on commit 381874d

Please sign in to comment.