systemprompt_models/wire/origin/
evidence.rs1use serde::{Deserialize, Serialize};
11
12use super::{ClientAttestation, ClientKind, NativeMarker};
13
14pub(super) const DECLARED_CLIENT_MAX: usize = 64;
15pub(super) const UA_PRODUCT_MAX: usize = 64;
16pub(super) const UA_VERSION_MAX: usize = 64;
17pub(super) const SDK_FIELD_MAX: usize = 64;
18
19#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
25pub struct ClientEvidence {
26 pub kind_source: ClientAttestation,
27 pub attested_host: Option<ClientKind>,
28 pub declared_client: Option<String>,
29 pub native_marker: Option<NativeMarker>,
30 pub ua_product: Option<String>,
31 pub ua_version: Option<String>,
32 pub sdk_lang: Option<String>,
33 pub sdk_package_version: Option<String>,
34 pub sdk_runtime: Option<String>,
35 pub sdk_runtime_version: Option<String>,
36 pub sdk_os: Option<String>,
37 pub sdk_arch: Option<String>,
38}
39
40impl ClientEvidence {
41 #[must_use]
42 pub const fn none() -> Self {
43 Self {
44 kind_source: ClientAttestation::None,
45 attested_host: None,
46 declared_client: None,
47 native_marker: None,
48 ua_product: None,
49 ua_version: None,
50 sdk_lang: None,
51 sdk_package_version: None,
52 sdk_runtime: None,
53 sdk_runtime_version: None,
54 sdk_os: None,
55 sdk_arch: None,
56 }
57 }
58
59 #[must_use]
60 pub const fn internal() -> Self {
61 let mut evidence = Self::none();
62 evidence.kind_source = ClientAttestation::Internal;
63 evidence
64 }
65}
66
67#[must_use]
68pub(super) fn bounded(value: Option<&str>, max: usize) -> Option<String> {
69 let value = value?.trim();
70 if value.is_empty() {
71 return None;
72 }
73 let mut end = value.len().min(max);
74 while !value.is_char_boundary(end) {
75 end -= 1;
76 }
77 Some(value[..end].to_owned())
78}