Skip to main content

cloud_sdk/diagnostics/
event.rs

1use crate::operation::{OperationId, OperationImpact, PreparedRequest};
2use crate::transport::StatusCode;
3use crate::{ProviderId, ServiceId};
4
5use super::{DiagnosticErrorCategory, DiagnosticRequestId, DiagnosticRetryCategory};
6
7/// Validated provider and operation context for one lifecycle event.
8#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
9pub struct DiagnosticContext {
10    provider: ProviderId,
11    service: ServiceId,
12    operation: Option<OperationId>,
13    impact: OperationImpact,
14    retry: DiagnosticRetryCategory,
15}
16
17impl DiagnosticContext {
18    pub(crate) const fn new(
19        provider: ProviderId,
20        service: ServiceId,
21        operation: Option<OperationId>,
22        impact: OperationImpact,
23        retry: DiagnosticRetryCategory,
24    ) -> Self {
25        Self {
26            provider,
27            service,
28            operation,
29            impact,
30            retry,
31        }
32    }
33
34    pub(crate) fn from_prepared(prepared: &PreparedRequest<'_>) -> Self {
35        let service = prepared.service();
36        Self::new(
37            service.provider_id(),
38            service.service_id(),
39            prepared.operation_id(),
40            prepared.metadata().impact(),
41            prepared.metadata().retry_eligibility().into(),
42        )
43    }
44
45    /// Returns the validated provider identifier.
46    #[must_use]
47    pub const fn provider(self) -> ProviderId {
48        self.provider
49    }
50
51    /// Returns the validated provider-owned service identifier.
52    #[must_use]
53    pub const fn service(self) -> ServiceId {
54        self.service
55    }
56
57    /// Returns the provider operation identifier when one was bound.
58    #[must_use]
59    pub const fn operation(self) -> Option<OperationId> {
60        self.operation
61    }
62
63    /// Returns the validated operation impact.
64    #[must_use]
65    pub const fn impact(self) -> OperationImpact {
66        self.impact
67    }
68
69    /// Returns the operation retry category.
70    #[must_use]
71    pub const fn retry(self) -> DiagnosticRetryCategory {
72        self.retry
73    }
74}
75
76/// Payload-free response metadata admitted for diagnostics.
77#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
78pub struct DiagnosticResponse {
79    status: StatusCode,
80    request_id: DiagnosticRequestId,
81}
82
83impl DiagnosticResponse {
84    pub(crate) const fn new(status: StatusCode, request_id: DiagnosticRequestId) -> Self {
85        Self { status, request_id }
86    }
87
88    /// Returns the bounded HTTP status code.
89    #[must_use]
90    pub const fn status(self) -> StatusCode {
91        self.status
92    }
93
94    /// Returns request-ID disposition without exposing identifier bytes.
95    #[must_use]
96    pub const fn request_id(self) -> DiagnosticRequestId {
97        self.request_id
98    }
99}
100
101/// Structured client lifecycle event containing no request or response payload.
102#[derive(Clone, Copy, Debug, Eq, PartialEq)]
103pub enum DiagnosticEvent {
104    /// A caller-owned workspace was cleared before preparation began.
105    PreparationStarted,
106    /// Provider preparation failed before an identity could be trusted.
107    PreparationFailed {
108        /// Payload-free failure category.
109        error: DiagnosticErrorCategory,
110    },
111    /// A complete provider request and policy context was prepared.
112    RequestPrepared {
113        /// Validated provider operation context.
114        context: DiagnosticContext,
115    },
116    /// One authenticated transport attempt is about to begin.
117    DispatchStarted {
118        /// Validated provider operation context.
119        context: DiagnosticContext,
120    },
121    /// Authenticated execution failed before checked decoding.
122    ExecutionFailed {
123        /// Validated provider operation context.
124        context: DiagnosticContext,
125        /// Payload-free failure category.
126        error: DiagnosticErrorCategory,
127    },
128    /// A committed bounded response was received.
129    ResponseReceived {
130        /// Validated provider operation context.
131        context: DiagnosticContext,
132        /// Admitted response metadata.
133        response: DiagnosticResponse,
134    },
135    /// Provider-owned checked decoding failed.
136    DecodeFailed {
137        /// Validated provider operation context.
138        context: DiagnosticContext,
139        /// Response metadata when a committed response was observable.
140        response: Option<DiagnosticResponse>,
141        /// Payload-free failure category.
142        error: DiagnosticErrorCategory,
143    },
144    /// One operation completed successfully.
145    Completed {
146        /// Validated provider operation context.
147        context: DiagnosticContext,
148        /// Response metadata when a committed response was observable.
149        response: Option<DiagnosticResponse>,
150    },
151}