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}