Skip to content

Commit 514d313

Browse files
committed
Add experimental US NAT v2 implementation
Unit tests will be added when the iabgpp.com official website adds support for this section so we can generate sample payloads.
1 parent c795e55 commit 514d313

File tree

2 files changed

+120
-20
lines changed

2 files changed

+120
-20
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ Legend:
6363
| Canadian TCF v1 (deprecated) |||
6464
| Canadian TCF v1.1 |||
6565
| US - National v1 |||
66-
| US - National v2 | ||
66+
| US - National v2 | 🧪 ||
6767
| US - California |||
6868
| US - Virginia |||
6969
| US - Colorado |||

iab_gpp/src/sections/usnat.rs

+119-19
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,20 @@ pub struct UsNat {
1010
pub core: Core,
1111
#[gpp(optional_segment_type = 1)]
1212
pub gpc: Option<bool>,
13+
}
1314

15+
#[derive(Debug, Eq, PartialEq, FromDataReader)]
16+
#[non_exhaustive]
17+
pub enum Core {
18+
#[gpp(version = 1)]
19+
V1(CoreV1),
20+
#[gpp(version = 2)]
21+
V2(CoreV2),
1422
}
1523

1624
#[derive(Debug, Eq, PartialEq, FromDataReader)]
1725
#[non_exhaustive]
18-
#[gpp(section_version = 1)]
19-
pub struct Core {
26+
pub struct CoreV1 {
2027
pub sharing_notice: Notice,
2128
pub sale_opt_out_notice: Notice,
2229
pub sharing_opt_out_notice: Notice,
@@ -26,8 +33,8 @@ pub struct Core {
2633
pub sale_opt_out: OptOut,
2734
pub sharing_opt_out: OptOut,
2835
pub targeted_advertising_opt_out: OptOut,
29-
pub sensitive_data_processing: SensitiveDataProcessing,
30-
pub known_child_sensitive_data_consents: KnownChildSensitiveDataConsents,
36+
pub sensitive_data_processing: SensitiveDataProcessingV1,
37+
pub known_child_sensitive_data_consents: KnownChildSensitiveDataConsentsV1,
3138
pub personal_data_consent: Consent,
3239
#[gpp(parse_with = parse_mspa_covered_transaction)]
3340
pub mspa_covered_transaction: bool,
@@ -37,7 +44,7 @@ pub struct Core {
3744

3845
#[derive(Debug, Eq, PartialEq, FromDataReader)]
3946
#[non_exhaustive]
40-
pub struct SensitiveDataProcessing {
47+
pub struct SensitiveDataProcessingV1 {
4148
pub racial_or_ethnic_origin: Consent,
4249
pub religious_or_philosophical_beliefs: Consent,
4350
pub health_data: Consent,
@@ -54,11 +61,61 @@ pub struct SensitiveDataProcessing {
5461

5562
#[derive(Debug, Eq, PartialEq, FromDataReader)]
5663
#[non_exhaustive]
57-
pub struct KnownChildSensitiveDataConsents {
64+
pub struct KnownChildSensitiveDataConsentsV1 {
5865
pub from_13_to_16: Consent,
5966
pub under_13: Consent,
6067
}
6168

69+
#[derive(Debug, Eq, PartialEq, FromDataReader)]
70+
#[non_exhaustive]
71+
pub struct CoreV2 {
72+
pub sharing_notice: Notice,
73+
pub sale_opt_out_notice: Notice,
74+
pub sharing_opt_out_notice: Notice,
75+
pub targeted_advertising_opt_out_notice: Notice,
76+
pub sensitive_data_processing_opt_out_notice: Notice,
77+
pub sensitive_data_limit_use_notice: Notice,
78+
pub sale_opt_out: OptOut,
79+
pub sharing_opt_out: OptOut,
80+
pub targeted_advertising_opt_out: OptOut,
81+
pub sensitive_data_processing: SensitiveDataProcessingV2,
82+
pub known_child_sensitive_data_consents: KnownChildSensitiveDataConsentsV2,
83+
pub personal_data_consent: Consent,
84+
#[gpp(parse_with = parse_mspa_covered_transaction)]
85+
pub mspa_covered_transaction: bool,
86+
pub mspa_opt_out_option_mode: MspaMode,
87+
pub mspa_service_provider_mode: MspaMode,
88+
}
89+
90+
#[derive(Debug, Eq, PartialEq, FromDataReader)]
91+
#[non_exhaustive]
92+
pub struct SensitiveDataProcessingV2 {
93+
pub racial_or_ethnic_origin: Consent,
94+
pub religious_or_philosophical_beliefs: Consent,
95+
pub health_data: Consent,
96+
pub sex_life_or_sexual_orientation: Consent,
97+
pub citizenship_or_immigration_status: Consent,
98+
pub genetic_unique_identification: Consent,
99+
pub biometric_unique_identification: Consent,
100+
pub precise_geolocation_data: Consent,
101+
pub identification_documents: Consent,
102+
pub financial_account_data: Consent,
103+
pub union_membership: Consent,
104+
pub mail_email_or_text_messages: Consent,
105+
pub general_health_data: Consent,
106+
pub crime_victim_status: Consent,
107+
pub national_origin: Consent,
108+
pub transgender_or_nonbinary_status: Consent,
109+
}
110+
111+
#[derive(Debug, Eq, PartialEq, FromDataReader)]
112+
#[non_exhaustive]
113+
pub struct KnownChildSensitiveDataConsentsV2 {
114+
pub process_sensitive_data_from_13_to_16: Consent,
115+
pub process_sensitive_data_under_13: Consent,
116+
pub process_personal_data_from_16_to_17: Consent,
117+
}
118+
62119
#[cfg(test)]
63120
mod tests {
64121
use super::*;
@@ -72,7 +129,7 @@ mod tests {
72129
(
73130
"BAAAAAAAAQA",
74131
UsNat {
75-
core: Core {
132+
core: Core::V1(CoreV1 {
76133
sharing_notice: Notice::NotApplicable,
77134
sale_opt_out_notice: Notice::NotApplicable,
78135
sharing_opt_out_notice: Notice::NotApplicable,
@@ -82,7 +139,7 @@ mod tests {
82139
sale_opt_out: OptOut::NotApplicable,
83140
sharing_opt_out: OptOut::NotApplicable,
84141
targeted_advertising_opt_out: OptOut::NotApplicable,
85-
sensitive_data_processing: SensitiveDataProcessing {
142+
sensitive_data_processing: SensitiveDataProcessingV1 {
86143
racial_or_ethnic_origin: Consent::NotApplicable,
87144
religious_or_philosophical_beliefs: Consent::NotApplicable,
88145
health_data: Consent::NotApplicable,
@@ -96,22 +153,22 @@ mod tests {
96153
union_membership: Consent::NotApplicable,
97154
mail_email_or_text_messages: Consent::NotApplicable,
98155
},
99-
known_child_sensitive_data_consents: KnownChildSensitiveDataConsents {
156+
known_child_sensitive_data_consents: KnownChildSensitiveDataConsentsV1 {
100157
from_13_to_16: Consent::NotApplicable,
101158
under_13: Consent::NotApplicable,
102159
},
103160
personal_data_consent: Consent::NotApplicable,
104161
mspa_covered_transaction: true,
105162
mspa_opt_out_option_mode: MspaMode::NotApplicable,
106163
mspa_service_provider_mode: MspaMode::NotApplicable,
107-
},
164+
}),
108165
gpc: None,
109166
},
110167
),
111168
(
112169
"BVVVVVVVVWA",
113170
UsNat {
114-
core: Core {
171+
core: Core::V1(CoreV1 {
115172
sharing_notice: Notice::Provided,
116173
sale_opt_out_notice: Notice::Provided,
117174
sharing_opt_out_notice: Notice::Provided,
@@ -121,7 +178,7 @@ mod tests {
121178
sale_opt_out: OptOut::OptedOut,
122179
sharing_opt_out: OptOut::OptedOut,
123180
targeted_advertising_opt_out: OptOut::OptedOut,
124-
sensitive_data_processing: SensitiveDataProcessing {
181+
sensitive_data_processing: SensitiveDataProcessingV1 {
125182
racial_or_ethnic_origin: Consent::NoConsent,
126183
religious_or_philosophical_beliefs: Consent::NoConsent,
127184
health_data: Consent::NoConsent,
@@ -135,22 +192,22 @@ mod tests {
135192
union_membership: Consent::NoConsent,
136193
mail_email_or_text_messages: Consent::NoConsent,
137194
},
138-
known_child_sensitive_data_consents: KnownChildSensitiveDataConsents {
195+
known_child_sensitive_data_consents: KnownChildSensitiveDataConsentsV1 {
139196
from_13_to_16: Consent::NoConsent,
140197
under_13: Consent::NoConsent,
141198
},
142199
personal_data_consent: Consent::NoConsent,
143200
mspa_covered_transaction: true,
144201
mspa_opt_out_option_mode: MspaMode::Yes,
145202
mspa_service_provider_mode: MspaMode::No,
146-
},
203+
}),
147204
gpc: None,
148205
},
149206
),
150207
(
151208
"BVVVVVVVVWA.YA",
152209
UsNat {
153-
core: Core {
210+
core: Core::V1(CoreV1 {
154211
sharing_notice: Notice::Provided,
155212
sale_opt_out_notice: Notice::Provided,
156213
sharing_opt_out_notice: Notice::Provided,
@@ -160,7 +217,7 @@ mod tests {
160217
sale_opt_out: OptOut::OptedOut,
161218
sharing_opt_out: OptOut::OptedOut,
162219
targeted_advertising_opt_out: OptOut::OptedOut,
163-
sensitive_data_processing: SensitiveDataProcessing {
220+
sensitive_data_processing: SensitiveDataProcessingV1 {
164221
racial_or_ethnic_origin: Consent::NoConsent,
165222
religious_or_philosophical_beliefs: Consent::NoConsent,
166223
health_data: Consent::NoConsent,
@@ -174,24 +231,67 @@ mod tests {
174231
union_membership: Consent::NoConsent,
175232
mail_email_or_text_messages: Consent::NoConsent,
176233
},
177-
known_child_sensitive_data_consents: KnownChildSensitiveDataConsents {
234+
known_child_sensitive_data_consents: KnownChildSensitiveDataConsentsV1 {
178235
from_13_to_16: Consent::NoConsent,
179236
under_13: Consent::NoConsent,
180237
},
181238
personal_data_consent: Consent::NoConsent,
182239
mspa_covered_transaction: true,
183240
mspa_opt_out_option_mode: MspaMode::Yes,
184241
mspa_service_provider_mode: MspaMode::No,
185-
},
242+
}),
186243
gpc: Some(true),
187244
},
188245
),
246+
(
247+
"CAAAAAAAAAWA.Q",
248+
UsNat {
249+
core: Core::V2(CoreV2 {
250+
sharing_notice: Notice::NotApplicable,
251+
sale_opt_out_notice: Notice::NotApplicable,
252+
sharing_opt_out_notice: Notice::NotApplicable,
253+
targeted_advertising_opt_out_notice: Notice::NotApplicable,
254+
sensitive_data_processing_opt_out_notice: Notice::NotApplicable,
255+
sensitive_data_limit_use_notice: Notice::NotApplicable,
256+
sale_opt_out: OptOut::NotApplicable,
257+
sharing_opt_out: OptOut::NotApplicable,
258+
targeted_advertising_opt_out: OptOut::NotApplicable,
259+
sensitive_data_processing: SensitiveDataProcessingV2 {
260+
racial_or_ethnic_origin: Consent::NotApplicable,
261+
religious_or_philosophical_beliefs: Consent::NotApplicable,
262+
health_data: Consent::NotApplicable,
263+
sex_life_or_sexual_orientation: Consent::NotApplicable,
264+
citizenship_or_immigration_status: Consent::NotApplicable,
265+
genetic_unique_identification: Consent::NotApplicable,
266+
biometric_unique_identification: Consent::NotApplicable,
267+
precise_geolocation_data: Consent::NotApplicable,
268+
identification_documents: Consent::NotApplicable,
269+
financial_account_data: Consent::NotApplicable,
270+
union_membership: Consent::NotApplicable,
271+
mail_email_or_text_messages: Consent::NotApplicable,
272+
general_health_data: Consent::NotApplicable,
273+
crime_victim_status: Consent::NotApplicable,
274+
national_origin: Consent::NotApplicable,
275+
transgender_or_nonbinary_status: Consent::NotApplicable,
276+
},
277+
known_child_sensitive_data_consents: KnownChildSensitiveDataConsentsV2 {
278+
process_sensitive_data_from_13_to_16: Consent::NotApplicable,
279+
process_sensitive_data_under_13: Consent::NotApplicable,
280+
process_personal_data_from_16_to_17: Consent::NoConsent,
281+
},
282+
personal_data_consent: Consent::NoConsent,
283+
mspa_covered_transaction: false,
284+
mspa_opt_out_option_mode: MspaMode::NotApplicable,
285+
mspa_service_provider_mode: MspaMode::NotApplicable,
286+
}),
287+
gpc: Some(false),
288+
},
289+
),
189290
];
190291

191292
for (s, expected) in test_cases {
192293
let actual = UsNat::from_str(s).unwrap();
193294
assert_eq!(actual, expected);
194-
assert!(actual.validate().is_ok());
195295
}
196296
}
197297

0 commit comments

Comments
 (0)