1use serde::{Deserialize, Serialize};
2
3use crate::{
4 codebook::CODEBOOK_SCHEMA,
5 codec::CODE_SCHEMA,
6 profile::{FibQuantProfileV1, NormFormat, PROFILE_SCHEMA},
7 rotation::ROTATION_ALGORITHM_VERSION,
8};
9
10pub const RECEIPT_SCHEMA: &str = "fib_quant_compression_receipt_v1";
11
12#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
14pub struct FibQuantCompressionReceiptV1 {
15 pub schema_version: String,
17 pub profile_digest: String,
19 pub codebook_digest: String,
21 pub rotation_digest: String,
23 pub source_vector_digest: String,
25 pub encoded_digest: String,
27 pub norm_format: NormFormat,
29 pub code_schema_version: String,
31 pub profile_schema_version: String,
33 pub codebook_schema_version: String,
35 pub ambient_dim: u32,
37 pub block_dim: u32,
39 pub codebook_size: u32,
41 pub paper_rate_bits_per_coord: f64,
43 pub wire_index_bits: u8,
45 pub wire_bits_per_coord: f64,
47 pub rotation_seed: u64,
49 pub rotation_algorithm_version: String,
51 pub codebook_seed: u64,
53 pub mse: Option<f64>,
55 pub cosine_similarity: Option<f64>,
57 pub fallback_available: bool,
59 pub recorded_unix_seconds: i64,
61}
62
63impl FibQuantCompressionReceiptV1 {
64 pub(crate) fn new(
65 profile: &FibQuantProfileV1,
66 profile_digest: String,
67 codebook_digest: String,
68 rotation_digest: String,
69 source_vector_digest: String,
70 encoded_digest: String,
71 ) -> Self {
72 Self {
73 schema_version: RECEIPT_SCHEMA.into(),
74 profile_digest,
75 codebook_digest,
76 rotation_digest,
77 source_vector_digest,
78 encoded_digest,
79 norm_format: profile.norm_format.clone(),
80 code_schema_version: CODE_SCHEMA.into(),
81 profile_schema_version: PROFILE_SCHEMA.into(),
82 codebook_schema_version: CODEBOOK_SCHEMA.into(),
83 ambient_dim: profile.ambient_dim,
84 block_dim: profile.block_dim,
85 codebook_size: profile.codebook_size,
86 paper_rate_bits_per_coord: profile.paper_rate_bits_per_coord,
87 wire_index_bits: profile.wire_index_bits,
88 wire_bits_per_coord: profile.wire_bits_per_coord,
89 rotation_seed: profile.rotation_seed,
90 rotation_algorithm_version: ROTATION_ALGORITHM_VERSION.into(),
91 codebook_seed: profile.codebook_seed,
92 mse: None,
93 cosine_similarity: None,
94 fallback_available: false,
95 recorded_unix_seconds: current_unix_seconds(),
96 }
97 }
98}
99
100fn current_unix_seconds() -> i64 {
101 std::time::SystemTime::now()
102 .duration_since(std::time::UNIX_EPOCH)
103 .map(|duration| duration.as_secs() as i64)
104 .unwrap_or(0)
105}