1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/// 4.2.3 Object: Bid
///
/// A SeatBid object contains one or more Bid objects, each of which relates to a specific
/// impression in the bid request via the impid attribute and constitutes an offer to buy that
/// impression for a given price.
#[derive(serde::Serialize, serde::Deserialize, Default, Debug, PartialEq, Clone)]
pub struct Bid<'a> {
    /// string; required
    /// Bidder generated bid ID to assist with logging/tracking.
    #[serde(borrow)]
    pub id: std::borrow::Cow<'a, str>,
    /// string; required
    /// ID of the Imp object in the related bid request.
    #[serde(borrow)]
    pub impid: std::borrow::Cow<'a, str>,
    /// float; required
    /// Bid price expressed as CPM although the actual transaction is for a unit impression only.
    /// Note that while the type indicates float, integer math is highly recommended when handling
    /// currencies (e.g., BigDecimal in Java).
    pub price: f64,
    /// string
    /// Win notice URL called by the exchange if the bid wins (not necessarily indicative of a
    /// delivered, viewed, or billable ad); optional means of serving ad markup. Substitution
    /// macros (Section 4.4) may be included in both the URL and optionally returned markup.
    #[serde(borrow, default, skip_serializing_if = "Option::is_none")]
    pub nurl: Option<std::borrow::Cow<'a, str>>,
    /// string
    /// Billing notice URL called by the exchange when a winning bid becomes billable based on
    /// exchange-specific business policy (e.g., typically delivered, viewed, etc.). Substitution
    /// macros (Section 4.4) may be included.
    #[serde(borrow, default, skip_serializing_if = "Option::is_none")]
    pub burl: Option<std::borrow::Cow<'a, str>>,
    /// string
    /// Loss notice URL called by the exchange when a bid is known to have been lost. Substitution
    /// macros (Section 4.4) may be included. Exchange-specific policy may preclude support for
    /// loss notices or the disclosure of winning clearing prices resulting in ${AUCTION_PRICE}
    /// macros being removed (i.e., replaced with a zero-length string).
    #[serde(borrow, default, skip_serializing_if = "Option::is_none")]
    pub lurl: Option<std::borrow::Cow<'a, str>>,
    /// string
    /// Optional means of conveying ad markup in case the bid wins; supersedes the win notice if
    /// markup is included in both. Substitution macros (Section 4.4) may be included.
    #[serde(borrow, default, skip_serializing_if = "Option::is_none")]
    pub adm: Option<std::borrow::Cow<'a, str>>,
    /// string
    /// ID of a preloaded ad to be served if the bid wins.
    #[serde(borrow, default, skip_serializing_if = "Option::is_none")]
    pub adid: Option<std::borrow::Cow<'a, str>>,
    /// string array
    /// Advertiser domain for block list checking (e.g., “ford.com”). This can be an array of for
    /// the case of rotating creatives. Exchanges can mandate that only one domain is allowed.
    #[serde(borrow, default, skip_serializing_if = "Option::is_none")]
    pub adomain: Option<Vec<std::borrow::Cow<'a, str>>>,
    /// string
    /// A platform-specific application identifier intended to be unique to the app and independent
    /// of the exchange. On Android, this should be a bundle or package name (e.g.,
    /// com.foo.mygame). On iOS, it is a numeric ID.
    #[serde(borrow, default, skip_serializing_if = "Option::is_none")]
    pub bundle: Option<std::borrow::Cow<'a, str>>,
    /// string
    /// URL without cache-busting to an image that is representative of the content of the campaign
    /// for ad quality/safety checking.
    #[serde(borrow, default, skip_serializing_if = "Option::is_none")]
    pub iurl: Option<std::borrow::Cow<'a, str>>,
    /// string
    /// Campaign ID to assist with ad quality checking; the collection of creatives for which iurl
    /// should be representative.
    #[serde(borrow, default, skip_serializing_if = "Option::is_none")]
    pub cid: Option<std::borrow::Cow<'a, str>>,
    /// string
    /// Creative ID to assist with ad quality checking.
    #[serde(borrow, default, skip_serializing_if = "Option::is_none")]
    pub crid: Option<std::borrow::Cow<'a, str>>,
    /// string
    /// Tactic ID to enable buyers to label bids for reporting to the exchange the tactic through
    /// which their bid was submitted. The specific usage and meaning of the tactic ID should be
    /// communicated between buyer and exchanges a priori.
    #[serde(borrow, default, skip_serializing_if = "Option::is_none")]
    pub tactic: Option<std::borrow::Cow<'a, str>>,
    /// string array
    /// IAB content categories of the creative. Refer to List 5.1.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub cat: Option<Vec<crate::ContentCategory>>,
    /// integer array
    /// Set of attributes describing the creative. Refer to List 5.3.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub attr: Option<Vec<crate::CreativeAttribute>>,
    /// integer
    /// API required by the markup if applicable. Refer to List 5.6.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub api: Option<crate::ApiFramework>,
    /// integer
    /// Video response protocol of the markup if applicable. Refer to List 5.8.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub protocol: Option<crate::Protocol>,
    /// integer
    /// Creative media rating per IQG guidelines. Refer to List 5.19.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub qagmediarating: Option<crate::IqgMediaRating>,
    /// string
    /// Language of the creative using ISO-639-1-alpha-2. The non- standard code “xx” may also be
    /// used if the creative has no linguistic content (e.g., a banner with just a company logo).
    // TODO: ISO-639-1-alpha-2
    #[serde(borrow, default, skip_serializing_if = "Option::is_none")]
    pub language: Option<std::borrow::Cow<'a, str>>,
    /// string
    /// Reference to the deal.id from the bid request if this bid pertains to a private marketplace
    /// direct deal.
    #[serde(borrow, default, skip_serializing_if = "Option::is_none")]
    pub dealid: Option<std::borrow::Cow<'a, str>>,
    /// integer
    /// Width of the creative in device independent pixels (DIPS).
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub w: Option<i32>,
    /// integer
    /// Height of the creative in device independent pixels (DIPS).
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub h: Option<i32>,
    /// integer
    /// Relative width of the creative when expressing size as a ratio. Required for Flex Ads.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub wratio: Option<i32>,
    /// integer
    /// Relative height of the creative when expressing size as a ratio. Required for Flex Ads.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub hratio: Option<i32>,
    /// integer
    /// Advisory as to the number of seconds the bidder is willing to wait between the auction and
    /// the actual impression.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub exp: Option<i32>,
    /// object
    /// Placeholder for bidder-specific extensions to OpenRTB.
    #[serde(borrow, default, skip_serializing_if = "Option::is_none")]
    pub ext: Option<json_ext::Object<'a>>,
}
#[cfg(test)]
mod test {
    use super::*;
    #[test]
    fn json() -> serde_json::Result<()> {
        assert!(serde_json::from_str::<Bid>("{}").is_err());
        let json = r#"{"id":"","impid":"","price":0.0}"#;
        let o1 = Bid::default();
        assert_eq!(serde_json::to_string(&o1)?, json);
        assert_eq!(o1, serde_json::from_str::<Bid>(json)?);
        Ok(())
    }
}