Skip to content

Commit 51fdae6

Browse files
committed
[+test] primitives - targeting - impl Output::try_get()
1 parent d6ed850 commit 51fdae6

File tree

3 files changed

+43
-3
lines changed

3 files changed

+43
-3
lines changed

primitives/src/targeting.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use chrono::Utc;
66
use std::collections::HashMap;
77

88
pub use eval::*;
9+
use serde_json::Number;
910

1011
mod eval;
1112

@@ -213,6 +214,23 @@ pub struct Output {
213214
pub price: HashMap<String, BigNum>,
214215
}
215216

217+
impl Output {
218+
fn try_get(&self, key: &str) -> Result<Value, Error> {
219+
match key {
220+
"show" => Ok(Value::Bool(self.show)),
221+
"boost" => {
222+
let boost = Number::from_f64(self.boost).ok_or(Error::TypeError)?;
223+
Ok(Value::Number(boost))
224+
},
225+
price_key if price_key.starts_with("price.") => {
226+
let price = self.price.get(price_key.trim_start_matches("price.")).ok_or(Error::UnknownVariable)?;
227+
Ok(Value::BigNum(price.clone()))
228+
},
229+
_ => Err(Error::UnknownVariable)
230+
}
231+
}
232+
}
233+
216234
impl From<&Channel> for Output {
217235
fn from(channel: &Channel) -> Self {
218236
let price = match &channel.spec.pricing_bounds {
@@ -325,6 +343,21 @@ mod test {
325343
assert!(input.try_get("adSlot.alexaRank").is_ok());
326344
}
327345

346+
#[test]
347+
fn test_try_get_of_output() {
348+
let output = Output {
349+
show: false,
350+
boost: 5.5,
351+
price: vec![("one".to_string(), 100.into())].into_iter().collect(),
352+
};
353+
354+
assert_eq!(Ok(Value::Bool(false)), output.try_get("show"));
355+
assert_eq!(Ok(Value::Number(Number::from_f64(5.5).expect("Should make a number"))), output.try_get("boost"));
356+
assert_eq!(Ok(Value::BigNum(100.into())), output.try_get("price.one"));
357+
assert_eq!(Err(Error::UnknownVariable), output.try_get("price.unknown"));
358+
assert_eq!(Err(Error::UnknownVariable), output.try_get("unknown"));
359+
}
360+
328361
#[test]
329362
fn test_output_from_channel() {
330363
use crate::channel::{Pricing, PricingBounds};

primitives/src/targeting/eval.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -944,7 +944,11 @@ fn eval(input: &Input, output: &mut Output, rule: &Rule) -> Result<Option<Value>
944944

945945
return Ok(None);
946946
}
947-
Function::Get(key) => Some(input.try_get(key)?),
947+
Function::Get(key) => match input.try_get(key) {
948+
Ok(value) => Some(value),
949+
Err(Error::UnknownVariable) => Some(output.try_get(key)?),
950+
Err(e) => return Err(e),
951+
},
948952
Function::Bn(value) => {
949953
let big_num = value.clone().try_bignum()?;
950954

primitives/src/targeting/eval_test.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1063,9 +1063,12 @@ mod control_flow_and_logic {
10631063
boost: 1.0,
10641064
price: Default::default(),
10651065
};
1066-
Rule::Function(Function::new_only_show_if(Value::Bool(true))).eval(&input, &mut output);
1066+
let result = Function::new_only_show_if(Value::Bool(true)).eval(&input, &mut output);
1067+
assert_eq!(Ok(None), result);
10671068
assert!(output.show);
1068-
Rule::Function(Function::new_only_show_if(Value::Bool(false))).eval(&input, &mut output);
1069+
1070+
let result = Function::new_only_show_if(Value::Bool(false)).eval(&input, &mut output);
1071+
assert_eq!(Ok(None), result);
10691072
assert!(!output.show);
10701073
}
10711074
#[test]

0 commit comments

Comments
 (0)