Skip to main content

wenlan_types/
lint_config.rs

1// SPDX-License-Identifier: Apache-2.0
2use super::contract::LintDigest;
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
6pub enum LintConfigSetting {
7    RerankerEnabled,
8    PageProjectionEnabled,
9    EpisodeChannelEnabled,
10    FactChannelEnabled,
11    SummaryPreludeEnabled,
12    TemporalGroundingEnabled,
13    KnowledgeGraphServingEnabled,
14    KnowledgeGraphSweepEnabled,
15    KnowledgeGraphProviderReady,
16    KnowledgeGraphHubCap,
17    SourceConfigurationCaptured,
18    SourceConfigurationCount,
19    SourceSnapshotIdentity,
20    PageRetrievalChannelEnabled,
21    FactChannelLimit,
22    RerankerLightConfigured,
23    RerankerDeepConfigured,
24    ProviderSlotsRequested,
25    ModelSlotsConfigured,
26    RerankerPathsRequested,
27    ModelConfigurationIdentity,
28    RuntimeObservationCaptured,
29    SemanticProviderReady,
30    SemanticProviderOnDevice,
31    SemanticExternalEgressEnabled,
32    SemanticCallingAgentEnabled,
33}
34
35#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
36pub enum LintConfigValue {
37    Enabled,
38    Disabled,
39    Count(u64),
40    Digest([u8; 32]),
41}
42
43#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
44pub struct LintConfigSelection {
45    setting: LintConfigSetting,
46    value: LintConfigValue,
47}
48
49impl LintConfigSelection {
50    pub const fn new(setting: LintConfigSetting, value: LintConfigValue) -> Self {
51        Self { setting, value }
52    }
53
54    pub const fn count(setting: LintConfigSetting, value: u64) -> Self {
55        Self {
56            setting,
57            value: LintConfigValue::Count(value),
58        }
59    }
60
61    pub const fn digest(setting: LintConfigSetting, value: [u8; 32]) -> Self {
62        Self {
63            setting,
64            value: LintConfigValue::Digest(value),
65        }
66    }
67
68    fn bytes(self) -> Vec<u8> {
69        let setting = match self.setting {
70            LintConfigSetting::RerankerEnabled => 1,
71            LintConfigSetting::PageProjectionEnabled => 2,
72            LintConfigSetting::EpisodeChannelEnabled => 3,
73            LintConfigSetting::FactChannelEnabled => 4,
74            LintConfigSetting::SummaryPreludeEnabled => 5,
75            LintConfigSetting::TemporalGroundingEnabled => 6,
76            LintConfigSetting::KnowledgeGraphServingEnabled => 7,
77            LintConfigSetting::KnowledgeGraphSweepEnabled => 8,
78            LintConfigSetting::KnowledgeGraphProviderReady => 9,
79            LintConfigSetting::KnowledgeGraphHubCap => 10,
80            LintConfigSetting::SourceConfigurationCaptured => 11,
81            LintConfigSetting::SourceConfigurationCount => 12,
82            LintConfigSetting::SourceSnapshotIdentity => 13,
83            LintConfigSetting::PageRetrievalChannelEnabled => 14,
84            LintConfigSetting::FactChannelLimit => 15,
85            LintConfigSetting::RerankerLightConfigured => 16,
86            LintConfigSetting::RerankerDeepConfigured => 17,
87            LintConfigSetting::ProviderSlotsRequested => 18,
88            LintConfigSetting::ModelSlotsConfigured => 19,
89            LintConfigSetting::RerankerPathsRequested => 20,
90            LintConfigSetting::ModelConfigurationIdentity => 21,
91            LintConfigSetting::RuntimeObservationCaptured => 22,
92            LintConfigSetting::SemanticProviderReady => 23,
93            LintConfigSetting::SemanticProviderOnDevice => 24,
94            LintConfigSetting::SemanticExternalEgressEnabled => 25,
95            LintConfigSetting::SemanticCallingAgentEnabled => 26,
96        };
97        let mut bytes = vec![setting];
98        match self.value {
99            LintConfigValue::Enabled => bytes.push(1),
100            LintConfigValue::Disabled => bytes.push(2),
101            LintConfigValue::Count(value) => {
102                bytes.push(3);
103                bytes.extend_from_slice(&value.to_le_bytes());
104            }
105            LintConfigValue::Digest(value) => {
106                bytes.push(4);
107                bytes.extend_from_slice(&value);
108            }
109        }
110        bytes
111    }
112}
113
114#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
115#[serde(transparent)]
116pub struct LintConfigFingerprint(LintDigest);
117
118impl LintConfigFingerprint {
119    pub fn from_effective_config(selections: &[LintConfigSelection]) -> Self {
120        let mut sorted = selections.to_vec();
121        sorted.sort_unstable();
122        let mut hash = 0xcbf2_9ce4_8422_2325_u64;
123        for selection in sorted {
124            for byte in selection.bytes() {
125                hash ^= u64::from(byte);
126                hash = hash.wrapping_mul(0x0000_0100_0000_01b3);
127            }
128        }
129        Self(LintDigest::from_u64(hash))
130    }
131
132    pub fn as_str(&self) -> &str {
133        self.0.as_str()
134    }
135}