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 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
/// Contains restriction types as defined in [`Vendor Consent String Format V2 Core String`]
///
/// [`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
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(PartialEq, Eq, Clone, PartialOrd, Hash, Debug)]
pub enum PublisherRestrictionType {
/// Purpose Flatly Not Allowed by Publisher
NotAllowed,
/// Specifies that vendors need to have consent
RequireConsent,
/// Specifies that vendors need to have "Legitimate Interest"
RequireLegitimateInterest,
/// Should not be used
Undefined,
}
/// `TcModelV2` contains all relevant fields specified in the [`Vendor Consent String Format V2`]
/// except for the `Version` field which is omitted
///
/// Note that the "Core String", "Disclosed Vendors", "Allowed Vendors" and "Publisher TC" segments are mapped into fields
///
/// "Core String" field mapping
/// * `Created` -> [`created_at`]
/// * `LastUpdated` -> [`updated_at`]
/// * `CmpId` -> [`cmp_id`]
/// * `CmpVersion` -> [`cmp_version`]
/// * `ConsentScreen` -> [`consent_screen`]
/// * `ConsentLanguage` -> [`consent_language`]
/// * `VendorListVersion` -> [`vendor_list_version`]
/// * `TcfPolicyVersion` -> [`tcf_policy_version`]
/// * `IsServiceSpecific` -> [`is_service_specific`]
/// * `UseNonStandardStacks` -> [`use_non_standard_stacks`]
/// * `SpecialFeatureOptIns` -> [`special_feature_opt_ins`]
/// * `PurposesConsent` -> [`purposes_consent`]
/// * `PurposesLITransparency` -> [`purposes_li_transparency`]
/// * `PurposeOneTreatment` -> [`purpose_one_treatment`]
/// * `PublisherCC` -> [`publisher_country_code`]
/// * `VendorsConsent` -> [`vendors_consent`]
/// * `VendorsLIConsent` -> [`vendors_li_consent`]
/// * `PublisherRestrictions` -> [`publisher_restrictions`]
///
/// "Disclosed Vendors" segment is mapped by the [`disclosed_vendors`] field
///
/// "Allowed Vendors" segment is mapped by the [`allowed_vendors`] field
///
/// "Publisher TC" field mapping
/// * `PubPurposesConsent` -> [`publisher_purposes_consent`]
/// * `PubPurposesLITransparency` -> [`publisher_purposes_li_transparency`]
/// * `CustomPurposesConsent` -> [`custom_purposes_consent`]
/// * `CustomPurposesLITransparency` -> [`custom_purposes_li_transparency`]
///
/// ```rust,edition2021
/// use std::convert::TryFrom;
/// // will return a Result which contains either the TcModel or an Error
/// // if the TCString could not be parsed or the TCString includes an unsupported version
/// let tc_model = lib_tcstring::TcModelV2::try_from("COvFyGBOvFyGBAbAAAENAPCAAOAAAAAAAAAAAEEUACCKAAA");
/// ```
///
/// [`created_at`]: struct.TcModelV2.html#structfield.created_at
/// [`updated_at`]: struct.TcModelV2.html#structfield.updated_at
/// [`cmp_id`]: struct.TcModelV2.html#structfield.cmp_id
/// [`cmp_version`]: struct.TcModelV2.html#structfield.cmp_version
/// [`consent_screen`]: struct.TcModelV2.html#structfield.consent_screen
/// [`consent_language`]: struct.TcModelV2.html#structfield.consent_language
/// [`vendor_list_version`]: struct.TcModelV2.html#structfield.vendor_list_version
/// [`tcf_policy_version`]: struct.TcModelV2.html#structfield.tcf_policy_version
/// [`is_service_specific`]: struct.TcModelV2.html#structfield.is_service_specific
/// [`use_non_standard_stacks`]: struct.TcModelV2.html#structfield.use_non_standard_stacks
/// [`special_feature_opt_ins`]: struct.TcModelV2.html#structfield.special_feature_opt_ins
/// [`purposes_consent`]: struct.TcModelV2.html#structfield.purposes_consent
/// [`purposes_li_transparency`]: struct.TcModelV2.html#structfield.purposes_li_transparency
/// [`purpose_one_treatment`]: struct.TcModelV2.html#structfield.purpose_one_treatment
/// [`publisher_country_code`]: struct.TcModelV2.html#structfield.publisher_country_code
/// [`vendors_consent`]: struct.TcModelV2.html#structfield.vendors_consent
/// [`vendors_li_consent`]: struct.TcModelV2.html#structfield.vendors_li_consent
/// [`publisher_restrictions`]: struct.TcModelV2.html#structfield.publisher_restrictions
/// [`disclosed_vendors`]: struct.TcModelV2.html#structfield.disclosed_vendors
/// [`allowed_vendors`]: struct.TcModelV2.html#structfield.allowed_vendors
/// [`publisher_purposes_consent`]: struct.TcModelV2.html#structfield.publisher_purposes_consent
/// [`publisher_purposes_li_transparency`]: struct.TcModelV2.html#structfield.publisher_purposes_li_transparency
/// [`custom_purposes_consent`]: struct.TcModelV2.html#structfield.custom_purposes_consent
/// [`custom_purposes_li_transparency`]: struct.TcModelV2.html#structfield.custom_purposes_li_transparency
/// [`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
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(PartialEq, Eq, Clone, PartialOrd, Hash, Debug, Default)]
pub struct TcModelV2 {
/// Epoch milliseconds when this TC String was first created
pub created_at: u64,
/// Epoch milliseconds when TC String was last updated
pub updated_at: u64,
/// Consent Management Platform ID that last updated the TC String
pub cmp_id: u16,
/// Consent Management Platform version of the CMP that last updated this TC String
pub cmp_version: u16,
/// CMP Screen number at which consent was given for a user with the CMP that last updated this TC String
pub consent_screen: u8,
/// [`ISO 639-1`] language code in which the CMP UI was presented
///
/// [`ISO 639-1`]: https://en.wikipedia.org/wiki/ISO_639-1
pub consent_language: String,
/// Version of the global vendor list used to create this TC String
pub vendor_list_version: u16,
/// Version of the corresponding field in the global vendor list that was used for obtaining consent
pub tcf_policy_version: u16,
/// Whether the signals encoded in this TC String were from service-specific storage (`true`) or shared storage (`false`)
pub is_service_specific: bool,
/// `true` means that a CMP is using customized Stack descriptions and not the standard stack descriptions
/// defined in the [`Policies`] (Appendix A, Section E)
///
/// `false` means standard stacks were used
///
/// [`Policies`]: https://iabeurope.eu/iab-europe-transparency-consent-framework-policies/#___E_Stacks__
pub use_non_standard_stacks: bool,
/// List of opted-in "Special Features"
///
/// "Special Features" are numerically identified in the global vendor list separately from normal features
pub special_feature_opt_ins: Vec<u8>,
/// List of allowed purposes
pub purposes_consent: Vec<u8>,
/// List of allowed "Legitimate Interest" purposes
pub purposes_li_transparency: Vec<u8>,
/// `true` means "Purpose 1" was not disclosed
///
/// `false` means "Purpose 1" was disclosed commonly as consent
pub purpose_one_treatment: bool,
/// [`ISO 3166-1 alpha-2`] code
///
/// [`ISO 3166-1 alpha-2`]: https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
pub publisher_country_code: String,
/// List of allowed vendors
pub vendors_consent: Vec<u16>,
/// List of vendors "Legitimate Interest" disclosures
pub vendors_li_consent: Vec<u16>,
/// List of publisher restrictions on a per purpose basis
///
/// See [`PublisherRestriction`] for more details
///
/// [`PublisherRestriction`]: struct.PublisherRestriction.html
pub publisher_restrictions: Vec<PublisherRestriction>,
/// List of vendors that have been disclosed to a given user by a CMP
pub disclosed_vendors: Vec<u16>,
/// List of vendors the publisher permits to use OOB legal bases
pub allowed_vendors: Vec<u16>,
/// List of purposes which are established on the legal basis of consent, for the publisher
pub publisher_purposes_consent: Vec<u8>,
/// List of purposes which are established on the legal basis of "Legitimate Interest" and the user has not exercised their “Right to Object”
pub publisher_purposes_li_transparency: Vec<u8>,
/// List of allowed custom purposes, for the publisher
pub custom_purposes_consent: Vec<u8>,
/// List of custom purposes which are are established on the legal basis of "Legitimate Interest"
pub custom_purposes_li_transparency: Vec<u8>,
}
/// Publisher restriction which overrides the specified purpose
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[derive(PartialEq, Eq, Clone, PartialOrd, Hash, Debug, Default)]
pub struct PublisherRestriction {
/// ID of publisher restricted purpose
pub purpose_id: u8,
/// publisher restriction for this purpose, see [`PublisherRestrictionType`] for more details
///
/// [`PublisherRestrictionType`]: enum.PublisherRestrictionType.html
pub restriction_type: PublisherRestrictionType,
/// List of relevant vendors
pub vendor_list: Vec<u16>,
}
#[cfg_attr(test, derive(Debug))]
pub(crate) enum RangeSectionType {
Vendor(Vec<u16>),
VendorLegitimateInterest(Vec<u16>),
PublisherRestriction(Vec<PublisherRestriction>),
}
#[cfg_attr(test, derive(Debug))]
pub(crate) struct TcSegment {
pub disclosed_vendors: Option<Vec<u16>>,
pub allowed_vendors: Option<Vec<u16>>,
pub publisher_tc: Option<PublisherTc>,
}
#[cfg_attr(test, derive(Debug))]
pub(crate) struct RangeSection {
pub last_bit: usize,
pub value: RangeSectionType,
}
#[cfg_attr(test, derive(Debug))]
#[derive(Default)]
pub(crate) struct PublisherTc {
pub publisher_purposes_consent: Vec<u8>,
pub publisher_purposes_li_transparency: Vec<u8>,
pub custom_purposes_consent: Vec<u8>,
pub custom_purposes_li_transparency: Vec<u8>,
}
impl Default for PublisherRestrictionType {
fn default() -> Self {
Self::Undefined
}
}