lib_tcstring/decode/model.rs
1/// Contains restriction types as defined in [`Vendor Consent String Format V2 Core String`]
2///
3/// [`Vendor Consent String Format V2 Core String`]: https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/81a3b9ed1545148be380b4408e6361cd2294446d/TCFv2/IAB%20Tech%20Lab%20-%20Consent%20string%20and%20vendor%20list%20formats%20v2.md#the-core-string
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5#[derive(PartialEq, Eq, Clone, PartialOrd, Hash, Debug)]
6pub enum PublisherRestrictionType {
7 /// Purpose Flatly Not Allowed by Publisher
8 NotAllowed,
9 /// Specifies that vendors need to have consent
10 RequireConsent,
11 /// Specifies that vendors need to have "Legitimate Interest"
12 RequireLegitimateInterest,
13 /// Should not be used
14 Undefined,
15}
16
17/// `TcModelV2` contains all relevant fields specified in the [`Vendor Consent String Format V2`]
18/// except for the `Version` field which is omitted
19///
20/// Note that the "Core String", "Disclosed Vendors", "Allowed Vendors" and "Publisher TC" segments are mapped into fields
21///
22/// "Core String" field mapping
23/// * `Created` -> [`created_at`]
24/// * `LastUpdated` -> [`updated_at`]
25/// * `CmpId` -> [`cmp_id`]
26/// * `CmpVersion` -> [`cmp_version`]
27/// * `ConsentScreen` -> [`consent_screen`]
28/// * `ConsentLanguage` -> [`consent_language`]
29/// * `VendorListVersion` -> [`vendor_list_version`]
30/// * `TcfPolicyVersion` -> [`tcf_policy_version`]
31/// * `IsServiceSpecific` -> [`is_service_specific`]
32/// * `UseNonStandardStacks` -> [`use_non_standard_stacks`]
33/// * `SpecialFeatureOptIns` -> [`special_feature_opt_ins`]
34/// * `PurposesConsent` -> [`purposes_consent`]
35/// * `PurposesLITransparency` -> [`purposes_li_transparency`]
36/// * `PurposeOneTreatment` -> [`purpose_one_treatment`]
37/// * `PublisherCC` -> [`publisher_country_code`]
38/// * `VendorsConsent` -> [`vendors_consent`]
39/// * `VendorsLIConsent` -> [`vendors_li_consent`]
40/// * `PublisherRestrictions` -> [`publisher_restrictions`]
41///
42/// "Disclosed Vendors" segment is mapped by the [`disclosed_vendors`] field
43///
44/// "Allowed Vendors" segment is mapped by the [`allowed_vendors`] field
45///
46/// "Publisher TC" field mapping
47/// * `PubPurposesConsent` -> [`publisher_purposes_consent`]
48/// * `PubPurposesLITransparency` -> [`publisher_purposes_li_transparency`]
49/// * `CustomPurposesConsent` -> [`custom_purposes_consent`]
50/// * `CustomPurposesLITransparency` -> [`custom_purposes_li_transparency`]
51///
52/// ```rust,edition2021
53/// use std::convert::TryFrom;
54/// // will return a Result which contains either the TcModel or an Error
55/// // if the TCString could not be parsed or the TCString includes an unsupported version
56/// let tc_model = lib_tcstring::TcModelV2::try_from("COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA");
57/// ```
58///
59/// [`created_at`]: struct.TcModelV2.html#structfield.created_at
60/// [`updated_at`]: struct.TcModelV2.html#structfield.updated_at
61/// [`cmp_id`]: struct.TcModelV2.html#structfield.cmp_id
62/// [`cmp_version`]: struct.TcModelV2.html#structfield.cmp_version
63/// [`consent_screen`]: struct.TcModelV2.html#structfield.consent_screen
64/// [`consent_language`]: struct.TcModelV2.html#structfield.consent_language
65/// [`vendor_list_version`]: struct.TcModelV2.html#structfield.vendor_list_version
66/// [`tcf_policy_version`]: struct.TcModelV2.html#structfield.tcf_policy_version
67/// [`is_service_specific`]: struct.TcModelV2.html#structfield.is_service_specific
68/// [`use_non_standard_stacks`]: struct.TcModelV2.html#structfield.use_non_standard_stacks
69/// [`special_feature_opt_ins`]: struct.TcModelV2.html#structfield.special_feature_opt_ins
70/// [`purposes_consent`]: struct.TcModelV2.html#structfield.purposes_consent
71/// [`purposes_li_transparency`]: struct.TcModelV2.html#structfield.purposes_li_transparency
72/// [`purpose_one_treatment`]: struct.TcModelV2.html#structfield.purpose_one_treatment
73/// [`publisher_country_code`]: struct.TcModelV2.html#structfield.publisher_country_code
74/// [`vendors_consent`]: struct.TcModelV2.html#structfield.vendors_consent
75/// [`vendors_li_consent`]: struct.TcModelV2.html#structfield.vendors_li_consent
76/// [`publisher_restrictions`]: struct.TcModelV2.html#structfield.publisher_restrictions
77/// [`disclosed_vendors`]: struct.TcModelV2.html#structfield.disclosed_vendors
78/// [`allowed_vendors`]: struct.TcModelV2.html#structfield.allowed_vendors
79/// [`publisher_purposes_consent`]: struct.TcModelV2.html#structfield.publisher_purposes_consent
80/// [`publisher_purposes_li_transparency`]: struct.TcModelV2.html#structfield.publisher_purposes_li_transparency
81/// [`custom_purposes_consent`]: struct.TcModelV2.html#structfield.custom_purposes_consent
82/// [`custom_purposes_li_transparency`]: struct.TcModelV2.html#structfield.custom_purposes_li_transparency
83/// [`Vendor Consent String Format V2`]: https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework/blob/81a3b9ed1545148be380b4408e6361cd2294446d/TCFv2/IAB%20Tech%20Lab%20-%20Consent%20string%20and%20vendor%20list%20formats%20v2.md#tc-string-format
84#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
85#[derive(PartialEq, Eq, Clone, PartialOrd, Hash, Debug, Default)]
86pub struct TcModelV2 {
87 /// Epoch milliseconds when this TC String was first created
88 pub created_at: u64,
89 /// Epoch milliseconds when TC String was last updated
90 pub updated_at: u64,
91 /// Consent Management Platform ID that last updated the TC String
92 pub cmp_id: u16,
93 /// Consent Management Platform version of the CMP that last updated this TC String
94 pub cmp_version: u16,
95 /// CMP Screen number at which consent was given for a user with the CMP that last updated this TC String
96 pub consent_screen: u8,
97 /// [`ISO 639-1`] language code in which the CMP UI was presented
98 ///
99 /// [`ISO 639-1`]: https://en.wikipedia.org/wiki/ISO_639-1
100 pub consent_language: String,
101 /// Version of the global vendor list used to create this TC String
102 pub vendor_list_version: u16,
103 /// Version of the corresponding field in the global vendor list that was used for obtaining consent
104 pub tcf_policy_version: u16,
105 /// Whether the signals encoded in this TC String were from service-specific storage (`true`) or shared storage (`false`)
106 pub is_service_specific: bool,
107 /// `true` means that a CMP is using customized Stack descriptions and not the standard stack descriptions
108 /// defined in the [`Policies`] (Appendix A, Section E)
109 ///
110 /// `false` means standard stacks were used
111 ///
112 /// [`Policies`]: https://iabeurope.eu/iab-europe-transparency-consent-framework-policies/#___E_Stacks__
113 pub use_non_standard_stacks: bool,
114 /// List of opted-in "Special Features"
115 ///
116 /// "Special Features" are numerically identified in the global vendor list separately from normal features
117 pub special_feature_opt_ins: Vec<u8>,
118 /// List of allowed purposes
119 pub purposes_consent: Vec<u8>,
120 /// List of allowed "Legitimate Interest" purposes
121 pub purposes_li_transparency: Vec<u8>,
122 /// `true` means "Purpose 1" was not disclosed
123 ///
124 /// `false` means "Purpose 1" was disclosed commonly as consent
125 pub purpose_one_treatment: bool,
126 /// [`ISO 3166-1 alpha-2`] code
127 ///
128 /// [`ISO 3166-1 alpha-2`]: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
129 pub publisher_country_code: String,
130 /// List of allowed vendors
131 pub vendors_consent: Vec<u16>,
132 /// List of vendors "Legitimate Interest" disclosures
133 pub vendors_li_consent: Vec<u16>,
134 /// List of publisher restrictions on a per purpose basis
135 ///
136 /// See [`PublisherRestriction`] for more details
137 ///
138 /// [`PublisherRestriction`]: struct.PublisherRestriction.html
139 pub publisher_restrictions: Vec<PublisherRestriction>,
140 /// List of vendors that have been disclosed to a given user by a CMP
141 pub disclosed_vendors: Vec<u16>,
142 /// List of vendors the publisher permits to use OOB legal bases
143 pub allowed_vendors: Vec<u16>,
144 /// List of purposes which are established on the legal basis of consent, for the publisher
145 pub publisher_purposes_consent: Vec<u8>,
146 /// List of purposes which are established on the legal basis of "Legitimate Interest" and the user has not exercised their “Right to Object”
147 pub publisher_purposes_li_transparency: Vec<u8>,
148 /// List of allowed custom purposes, for the publisher
149 pub custom_purposes_consent: Vec<u8>,
150 /// List of custom purposes which are are established on the legal basis of "Legitimate Interest"
151 pub custom_purposes_li_transparency: Vec<u8>,
152}
153
154/// Publisher restriction which overrides the specified purpose
155#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
156#[derive(PartialEq, Eq, Clone, PartialOrd, Hash, Debug, Default)]
157pub struct PublisherRestriction {
158 /// ID of publisher restricted purpose
159 pub purpose_id: u8,
160 /// publisher restriction for this purpose, see [`PublisherRestrictionType`] for more details
161 ///
162 /// [`PublisherRestrictionType`]: enum.PublisherRestrictionType.html
163 pub restriction_type: PublisherRestrictionType,
164 /// List of relevant vendors
165 pub vendor_list: Vec<u16>,
166}
167
168#[cfg_attr(test, derive(Debug))]
169pub(crate) enum RangeSectionType {
170 Vendor(Vec<u16>),
171 VendorLegitimateInterest(Vec<u16>),
172 PublisherRestriction(Vec<PublisherRestriction>),
173}
174
175#[cfg_attr(test, derive(Debug))]
176pub(crate) struct TcSegment {
177 pub disclosed_vendors: Option<Vec<u16>>,
178 pub allowed_vendors: Option<Vec<u16>>,
179 pub publisher_tc: Option<PublisherTc>,
180}
181
182#[cfg_attr(test, derive(Debug))]
183pub(crate) struct RangeSection {
184 pub last_bit: usize,
185 pub value: RangeSectionType,
186}
187
188#[cfg_attr(test, derive(Debug))]
189#[derive(Default)]
190pub(crate) struct PublisherTc {
191 pub publisher_purposes_consent: Vec<u8>,
192 pub publisher_purposes_li_transparency: Vec<u8>,
193 pub custom_purposes_consent: Vec<u8>,
194 pub custom_purposes_li_transparency: Vec<u8>,
195}
196
197impl Default for PublisherRestrictionType {
198 fn default() -> Self {
199 Self::Undefined
200 }
201}