1#![doc = "Generated transport-independent contract objects."]
3
4use std::collections::BTreeMap;
5use std::error::Error as StdError;
6use std::fmt::{self, Display, Formatter};
7
8use serde::{Deserialize, Deserializer, Serialize, Serializer};
9use serde_json::Value;
10use spiral_contract::error::{ErrorEnvelope, ServiceError};
11use spiral_contract::safelong::{SafeLong, SafeUnsignedLong};
12use spiral_contract::strict::{DeserializeStrict, Strict};
13use uuid::Uuid;
14
15#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
20pub struct ArborScanUsage {
21 #[serde(rename = "filesConsidered")]
23 pub files_considered: SafeUnsignedLong,
24 #[serde(rename = "filesPruned")]
26 pub files_pruned: SafeUnsignedLong,
27 #[serde(rename = "finished")]
29 pub finished: bool,
30 #[serde(rename = "fragmentsConsidered")]
32 pub fragments_considered: SafeUnsignedLong,
33 #[serde(rename = "fragmentsPruned")]
35 pub fragments_pruned: SafeUnsignedLong,
36 #[serde(rename = "outputRows")]
38 pub output_rows: SafeUnsignedLong,
39 #[serde(rename = "storage")]
41 #[serde(default, skip_serializing_if = "Option::is_none")]
42 pub storage: Option<StorageReads>,
43}
44impl<'de> DeserializeStrict<'de> for ArborScanUsage {
45 fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
46 #[derive(Deserialize)]
47 #[serde(deny_unknown_fields)]
48 struct __Wire {
49 #[serde(rename = "filesConsidered")]
50 files_considered: Strict<SafeUnsignedLong>,
51 #[serde(rename = "filesPruned")]
52 files_pruned: Strict<SafeUnsignedLong>,
53 #[serde(rename = "finished")]
54 finished: Strict<bool>,
55 #[serde(rename = "fragmentsConsidered")]
56 fragments_considered: Strict<SafeUnsignedLong>,
57 #[serde(rename = "fragmentsPruned")]
58 fragments_pruned: Strict<SafeUnsignedLong>,
59 #[serde(rename = "outputRows")]
60 output_rows: Strict<SafeUnsignedLong>,
61 #[serde(rename = "storage")]
62 #[serde(default)]
63 storage: Strict<Option<StorageReads>>,
64 }
65 let wire = __Wire::deserialize(deserializer)?;
66 Ok(Self {
67 files_considered: wire.files_considered.0,
68 files_pruned: wire.files_pruned.0,
69 finished: wire.finished.0,
70 fragments_considered: wire.fragments_considered.0,
71 fragments_pruned: wire.fragments_pruned.0,
72 output_rows: wire.output_rows.0,
73 storage: wire.storage.0,
74 })
75 }
76}
77
78#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
80#[serde(transparent)]
81pub struct ProjectId(pub String);
82impl std::fmt::Display for ProjectId {
83 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
84 self.0.fmt(formatter)
85 }
86}
87impl<'de> DeserializeStrict<'de> for ProjectId {
88 fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
89 Ok(Self(Strict::<String>::deserialize(deserializer)?.0))
90 }
91}
92
93#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
96pub struct ReportUsageRecordsRequest {
97 #[serde(rename = "records")]
99 pub records: Vec<UsageRecord>,
100}
101impl<'de> DeserializeStrict<'de> for ReportUsageRecordsRequest {
102 fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
103 #[derive(Deserialize)]
104 #[serde(deny_unknown_fields)]
105 struct __Wire {
106 #[serde(rename = "records")]
107 records: Strict<Vec<UsageRecord>>,
108 }
109 let wire = __Wire::deserialize(deserializer)?;
110 Ok(Self {
111 records: wire.records.0,
112 })
113 }
114}
115
116#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
119pub struct ReportUsageRequest {
120 #[serde(rename = "events")]
122 pub events: Vec<UsageEvent>,
123 #[serde(rename = "projectId")]
125 #[serde(default, skip_serializing_if = "Option::is_none")]
126 pub project_id: Option<String>,
127 #[serde(rename = "tableId")]
129 #[serde(default, skip_serializing_if = "Option::is_none")]
130 pub table_id: Option<String>,
131}
132impl<'de> DeserializeStrict<'de> for ReportUsageRequest {
133 fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
134 #[derive(Deserialize)]
135 #[serde(deny_unknown_fields)]
136 struct __Wire {
137 #[serde(rename = "events")]
138 events: Strict<Vec<UsageEvent>>,
139 #[serde(rename = "projectId")]
140 #[serde(default)]
141 project_id: Strict<Option<String>>,
142 #[serde(rename = "tableId")]
143 #[serde(default)]
144 table_id: Strict<Option<String>>,
145 }
146 let wire = __Wire::deserialize(deserializer)?;
147 Ok(Self {
148 events: wire.events.0,
149 project_id: wire.project_id.0,
150 table_id: wire.table_id.0,
151 })
152 }
153}
154
155#[derive(Clone, Debug, PartialEq, Eq)]
163pub enum StorageReadScope {
164 Complete,
166 Direct,
168 Unknown(String),
170}
171impl Serialize for StorageReadScope {
172 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
173 serializer.serialize_str(match self {
174 Self::Complete => "complete",
175 Self::Direct => "direct",
176 Self::Unknown(value) => value,
177 })
178 }
179}
180impl<'de> Deserialize<'de> for StorageReadScope {
181 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
182 Ok(match String::deserialize(deserializer)?.as_str() {
183 "complete" => Self::Complete,
184 "direct" => Self::Direct,
185 value => Self::Unknown(value.to_owned()),
186 })
187 }
188}
189impl<'de> DeserializeStrict<'de> for StorageReadScope {
190 fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
191 #[derive(Deserialize)]
192 enum __Known {
193 #[serde(rename = "complete")]
194 Complete,
195 #[serde(rename = "direct")]
196 Direct,
197 }
198 Ok(match __Known::deserialize(deserializer)? {
199 __Known::Complete => Self::Complete,
200 __Known::Direct => Self::Direct,
201 })
202 }
203}
204
205#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
208pub struct StorageReads {
209 #[serde(rename = "bytes")]
211 pub bytes: SafeUnsignedLong,
212 #[serde(rename = "readTimeNs")]
214 pub read_time_ns: SafeUnsignedLong,
215 #[serde(rename = "requests")]
217 pub requests: SafeUnsignedLong,
218 #[serde(rename = "scope")]
220 pub scope: StorageReadScope,
221}
222impl<'de> DeserializeStrict<'de> for StorageReads {
223 fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
224 #[derive(Deserialize)]
225 #[serde(deny_unknown_fields)]
226 struct __Wire {
227 #[serde(rename = "bytes")]
228 bytes: Strict<SafeUnsignedLong>,
229 #[serde(rename = "readTimeNs")]
230 read_time_ns: Strict<SafeUnsignedLong>,
231 #[serde(rename = "requests")]
232 requests: Strict<SafeUnsignedLong>,
233 #[serde(rename = "scope")]
234 scope: Strict<StorageReadScope>,
235 }
236 let wire = __Wire::deserialize(deserializer)?;
237 Ok(Self {
238 bytes: wire.bytes.0,
239 read_time_ns: wire.read_time_ns.0,
240 requests: wire.requests.0,
241 scope: wire.scope.0,
242 })
243 }
244}
245
246#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
249pub struct UsageEvent {
250 #[serde(rename = "eventType")]
252 pub event_type: String,
253 #[serde(rename = "properties")]
255 pub properties: BTreeMap<String, Value>,
256}
257impl<'de> DeserializeStrict<'de> for UsageEvent {
258 fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
259 #[derive(Deserialize)]
260 #[serde(deny_unknown_fields)]
261 struct __Wire {
262 #[serde(rename = "eventType")]
263 event_type: Strict<String>,
264 #[serde(rename = "properties")]
265 properties: Strict<BTreeMap<String, Value>>,
266 }
267 let wire = __Wire::deserialize(deserializer)?;
268 Ok(Self {
269 event_type: wire.event_type.0,
270 properties: wire.properties.0,
271 })
272 }
273}
274
275#[derive(Clone, Debug, PartialEq, Eq)]
280pub enum UsageMeasurement {
281 ArborScanV1(ArborScanUsage),
283 Unknown { tag: String, value: Value },
285}
286impl Serialize for UsageMeasurement {
287 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
288 match self {
289 Self::ArborScanV1(value) => {
290 let mut object = serde_json::Map::new();
291 object.insert("type".into(), Value::String("arborScanV1".into()));
292 object.insert(
293 "arborScanV1".into(),
294 serde_json::to_value(value).map_err(serde::ser::Error::custom)?,
295 );
296 Value::Object(object).serialize(serializer)
297 }
298 Self::Unknown { tag, value } => {
299 if value.get("type").and_then(Value::as_str) != Some(tag.as_str()) {
300 return Err(serde::ser::Error::custom(
301 "unknown union discriminator mismatch",
302 ));
303 }
304 value.serialize(serializer)
305 }
306 }
307 }
308}
309impl<'de> Deserialize<'de> for UsageMeasurement {
310 fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
311 let value = Value::deserialize(deserializer)?;
312 let tag = value
313 .get("type")
314 .and_then(Value::as_str)
315 .ok_or_else(|| serde::de::Error::custom("union requires type"))?;
316 match tag {
317 "arborScanV1" => Ok(Self::ArborScanV1(
318 serde_json::from_value(
319 value
320 .get("arborScanV1")
321 .cloned()
322 .ok_or_else(|| serde::de::Error::custom("union requires matching arm"))?,
323 )
324 .map_err(serde::de::Error::custom)?,
325 )),
326 tag => Ok(Self::Unknown {
327 tag: tag.to_owned(),
328 value,
329 }),
330 }
331 }
332}
333impl<'de> DeserializeStrict<'de> for UsageMeasurement {
334 fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
335 #[derive(Deserialize)]
336 enum __Tag0 {
337 #[serde(rename = "arborScanV1")]
338 Value,
339 }
340 #[derive(Deserialize)]
341 #[serde(deny_unknown_fields)]
342 struct __Arm0 {
343 #[serde(rename = "type")]
344 _tag: __Tag0,
345 #[serde(rename = "arborScanV1")]
346 value: Strict<ArborScanUsage>,
347 }
348 #[derive(Deserialize)]
349 #[serde(untagged)]
350 enum __Known {
351 ArborScanV1(Box<__Arm0>),
352 }
353 Ok(match __Known::deserialize(deserializer)? {
354 __Known::ArborScanV1(arm) => Self::ArborScanV1(arm.value.0),
355 })
356 }
357}
358
359#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
365pub struct UsageRecord {
366 #[serde(rename = "emitterVersion")]
368 pub emitter_version: String,
369 #[serde(rename = "id")]
371 pub id: Uuid,
372 #[serde(rename = "measurement")]
374 pub measurement: UsageMeasurement,
375 #[serde(rename = "occurredAtMicros")]
377 pub occurred_at_micros: SafeLong,
378 #[serde(rename = "resourceId")]
380 #[serde(default, skip_serializing_if = "Option::is_none")]
381 pub resource_id: Option<Uuid>,
382 #[serde(rename = "source")]
384 pub source: String,
385 #[serde(rename = "versionId")]
387 #[serde(default, skip_serializing_if = "Option::is_none")]
388 pub version_id: Option<Uuid>,
389}
390impl<'de> DeserializeStrict<'de> for UsageRecord {
391 fn deserialize_strict<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
392 #[derive(Deserialize)]
393 #[serde(deny_unknown_fields)]
394 struct __Wire {
395 #[serde(rename = "emitterVersion")]
396 emitter_version: Strict<String>,
397 #[serde(rename = "id")]
398 id: Strict<Uuid>,
399 #[serde(rename = "measurement")]
400 measurement: Strict<UsageMeasurement>,
401 #[serde(rename = "occurredAtMicros")]
402 occurred_at_micros: Strict<SafeLong>,
403 #[serde(rename = "resourceId")]
404 #[serde(default)]
405 resource_id: Strict<Option<Uuid>>,
406 #[serde(rename = "source")]
407 source: Strict<String>,
408 #[serde(rename = "versionId")]
409 #[serde(default)]
410 version_id: Strict<Option<Uuid>>,
411 }
412 let wire = __Wire::deserialize(deserializer)?;
413 Ok(Self {
414 emitter_version: wire.emitter_version.0,
415 id: wire.id.0,
416 measurement: wire.measurement.0,
417 occurred_at_micros: wire.occurred_at_micros.0,
418 resource_id: wire.resource_id.0,
419 source: wire.source.0,
420 version_id: wire.version_id.0,
421 })
422 }
423}
424
425#[derive(Clone, Debug, PartialEq, Eq)]
427pub enum UsageError {
428 Conflict { reason: String },
430 InvalidArgument { reason: String },
432 NotFound { resource: String },
434}
435impl UsageError {
436 pub fn status(&self) -> u16 {
438 match self {
439 Self::Conflict { .. } => 409,
440 Self::InvalidArgument { .. } => 400,
441 Self::NotFound { .. } => 404,
442 }
443 }
444 pub fn envelope(&self, instance: String) -> ErrorEnvelope {
446 match self {
447 Self::Conflict { reason } => {
448 let mut envelope = ErrorEnvelope::new("CONFLICT", "Usage:Conflict", instance);
449 envelope
450 .parameters
451 .insert("reason".into(), reason.to_string());
452 envelope
453 }
454 Self::InvalidArgument { reason } => {
455 let mut envelope =
456 ErrorEnvelope::new("INVALID_ARGUMENT", "Usage:InvalidArgument", instance);
457 envelope
458 .parameters
459 .insert("reason".into(), reason.to_string());
460 envelope
461 }
462 Self::NotFound { resource } => {
463 let mut envelope = ErrorEnvelope::new("NOT_FOUND", "Usage:NotFound", instance);
464 envelope
465 .parameters
466 .insert("resource".into(), resource.to_string());
467 envelope
468 }
469 }
470 }
471 pub fn decode_envelope(envelope: &ErrorEnvelope) -> Option<Self> {
473 if envelope.error_instance_id.len() != 36
474 || Uuid::parse_str(&envelope.error_instance_id).is_err()
475 {
476 return None;
477 }
478 match envelope.error_name.as_str() {
479 "Usage:Conflict" => {
480 if envelope.error_code != "CONFLICT" {
481 return None;
482 }
483 let reason = envelope.parameters.get("reason")?.clone();
484 Some(Self::Conflict { reason })
485 }
486 "Usage:InvalidArgument" => {
487 if envelope.error_code != "INVALID_ARGUMENT" {
488 return None;
489 }
490 let reason = envelope.parameters.get("reason")?.clone();
491 Some(Self::InvalidArgument { reason })
492 }
493 "Usage:NotFound" => {
494 if envelope.error_code != "NOT_FOUND" {
495 return None;
496 }
497 let resource = envelope.parameters.get("resource")?.clone();
498 Some(Self::NotFound { resource })
499 }
500 _ => None,
501 }
502 }
503}
504impl Display for UsageError {
505 fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
506 match self {
507 Self::Conflict { reason } => write!(formatter, "Usage:Conflict (reason: {})", reason),
508 Self::InvalidArgument { reason } => {
509 write!(formatter, "Usage:InvalidArgument (reason: {})", reason)
510 }
511 Self::NotFound { resource } => {
512 write!(formatter, "Usage:NotFound (resource: {})", resource)
513 }
514 }
515 }
516}
517impl StdError for UsageError {}
518impl ServiceError for UsageError {
519 fn to_envelope(&self, instance: String) -> ErrorEnvelope {
520 Self::envelope(self, instance)
521 }
522 fn from_envelope(envelope: &ErrorEnvelope) -> Option<Self> {
523 Self::decode_envelope(envelope)
524 }
525}