Skip to content

Commit 9a245a1

Browse files
committed
Input Source & Map
1 parent f5fdb55 commit 9a245a1

File tree

4 files changed

+89
-10
lines changed

4 files changed

+89
-10
lines changed

adview-manager/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use adex_primitives::{
55
supermarket::units_for_slot::response::{AdUnit, Campaign, Response},
6-
targeting::{AdView, Input},
6+
targeting::{AdView, InputSource},
77
BigNum, ChannelId, SpecValidators,
88
};
99
use chrono::{DateTime, Utc};
@@ -268,7 +268,7 @@ impl Manager {
268268
Self { options, history }
269269
}
270270

271-
pub fn get_targeting_input(&self, mut input: Input, channel_id: ChannelId) -> Input {
271+
pub fn get_targeting_input(&self, mut input: InputSource, channel_id: ChannelId) -> InputSource {
272272
let seconds_since_campaign_impression = self
273273
.history
274274
.iter()

primitives/src/supermarket.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ pub enum Finalized {
4242

4343
pub mod units_for_slot {
4444
pub mod response {
45-
use crate::{targeting::Rule, BigNum, ChannelId, ChannelSpec, SpecValidators, ValidatorId};
45+
use crate::{targeting::{Input, Rule, InputMap}, BigNum, ChannelId, ChannelSpec, SpecValidators, ValidatorId};
4646
use chrono::{
4747
serde::{ts_milliseconds, ts_milliseconds_option},
4848
DateTime, Utc,
@@ -53,8 +53,7 @@ pub mod units_for_slot {
5353
#[derive(Debug, Serialize, Deserialize)]
5454
#[serde(rename_all = "camelCase")]
5555
pub struct Response {
56-
// TODO: This should be Input, however, we only need the fields and not the Global: Channel, Status & BalancesMap
57-
pub targeting_input_base: (),
56+
pub targeting_input_base: InputMap,
5857
pub accepted_referrers: Vec<Url>,
5958
pub fallback_unit: AdUnit,
6059
pub campaigns: Vec<Campaign>,

primitives/src/targeting.rs

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,40 @@ use std::collections::HashMap;
77

88
pub use eval::*;
99
use serde_json::Number;
10+
use serde::{Serialize};
1011

1112
mod eval;
1213

13-
#[derive(Debug, Clone)]
14-
pub struct Input {
14+
pub type InputMap = HashMap<String, Value>;
15+
16+
#[derive(Debug)]
17+
pub enum Input {
18+
Map {
19+
inner: InputMap,
20+
deposit_asset: String,
21+
},
22+
InputSource(InputSource),
23+
}
24+
25+
impl Input {
26+
pub fn get(&self, key: &str) -> Result<Value, Error> {
27+
match self {
28+
Input::Map{inner, ..} => inner.get(key).ok_or(Error::UnknownVariable).map(Clone::clone),
29+
Input::InputSource(input) => input.try_get(key)
30+
}
31+
}
32+
33+
pub fn deposit_asset(&self) -> Value {
34+
match self {
35+
Input::Map{deposit_asset, ..} => Value::new_string(deposit_asset),
36+
Input::InputSource(input) => Value::new_string(&input.global.channel.deposit_asset)
37+
}
38+
}
39+
}
40+
41+
#[derive(Debug, Clone, Serialize)]
42+
#[serde(into = "InputMap")]
43+
pub struct InputSource {
1544
/// AdView scope, accessible only on the AdView
1645
pub ad_view: Option<AdView>,
1746
/// Global scope, accessible everywhere
@@ -20,7 +49,57 @@ pub struct Input {
2049
pub ad_slot: Option<AdSlot>,
2150
}
2251

23-
impl Input {
52+
impl From<Input> for InputMap {
53+
fn from(input: Input) -> Self {
54+
let mut map = Self::new();
55+
56+
let fields = [
57+
// AdView scope, accessible only on the AdView
58+
"adView.secondsSinceCampaignImpression",
59+
"adView.hasCustomPreferences",
60+
"adView.navigatorLanguage",
61+
// Global scope, accessible everywhere
62+
"adSlotId",
63+
"adSlotType",
64+
"publisherId",
65+
"country",
66+
"eventType",
67+
"secondsSinceEpoch",
68+
"userAgentOS",
69+
"userAgentBrowserFamily",
70+
// Global scope, accessible everywhere, campaign-dependant
71+
"adUnitId",
72+
"advertiserId",
73+
"campaignId",
74+
"campaignTotalSpent",
75+
"campaignSecondsActive",
76+
"campaignSecondsDuration",
77+
"campaignBudget",
78+
"eventMinPrice",
79+
"eventMaxPrice",
80+
"publisherEarnedFromCampaign",
81+
// adSlot scope, accessible on Supermarket and AdView
82+
"adSlot.categories",
83+
"adSlot.hostname",
84+
"adSlot.alexaRank",
85+
];
86+
87+
for field in fields.iter() {
88+
match input.try_get(field) {
89+
Ok(value) => {
90+
// we don't care if there is an old value, there shouldn't be one!
91+
map.insert(field.to_string(), value);
92+
},
93+
// if there is an Error, it will be `UnknownVariable` and we just skip it
94+
Err(_) => {},
95+
}
96+
}
97+
98+
map
99+
}
100+
}
101+
102+
impl InputSource {
24103
fn try_get(&self, key: &str) -> Result<Value, Error> {
25104
let spec = &self.global.channel.spec;
26105

@@ -107,6 +186,7 @@ impl Input {
107186

108187
Ok(Value::Number(seconds.into()))
109188
}
189+
"depositAsset" => Ok(Value::new_string(&self.global.channel.deposit_asset)),
110190
"campaignBudget" => Ok(Value::BigNum(self.global.channel.deposit_amount.clone())),
111191
"eventMinPrice" => {
112192
let min = get_pricing_bounds(&self.global.channel, &self.global.event_type).min;

primitives/src/targeting/eval.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -893,10 +893,10 @@ fn eval(input: &Input, output: &mut Output, rule: &Rule) -> Result<Option<Value>
893893
.eval(input, output)?
894894
.ok_or(Error::TypeError)?
895895
.try_bignum()?;
896-
let deposit_asset = &input.global.channel.deposit_asset;
896+
let deposit_asset = input.deposit_asset()?.try_string()?;
897897

898898
let divisor = DEPOSIT_ASSETS_MAP
899-
.get(deposit_asset)
899+
.get(&deposit_asset)
900900
.ok_or(Error::TypeError)?;
901901
let amount_in_usd = amount.div(divisor).to_f64().ok_or(Error::TypeError)?;
902902
let amount_as_number = Number::from_f64(amount_in_usd).ok_or(Error::TypeError)?;

0 commit comments

Comments
 (0)