129 lines
4.2 KiB
Rust
129 lines
4.2 KiB
Rust
//! Stable typed outcomes for the Kaptan configuration microservice.
|
|
|
|
use kaptan_config::{ConfigState, ConfigViolation, FieldId};
|
|
use kaptan_err_reportable::KaptanError;
|
|
|
|
/// Operation reported in an authoritative result record.
|
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
pub enum Operation {
|
|
/// Query/read operation.
|
|
Query,
|
|
/// Begin transaction.
|
|
Begin,
|
|
/// Scalar write.
|
|
Set,
|
|
/// Whole-candidate validation.
|
|
Validate,
|
|
/// Durable commit.
|
|
Commit,
|
|
/// Transaction abort.
|
|
Abort,
|
|
}
|
|
|
|
/// Stable result classification.
|
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
pub enum ResultKind {
|
|
/// The operation was accepted.
|
|
Accepted,
|
|
/// A full snapshot committed but requires restart before activation.
|
|
CommittedRestartRequired,
|
|
/// The operation was rejected without an active-state transition.
|
|
Rejected,
|
|
}
|
|
|
|
/// Compact protocol error code. Detail belongs in [`ConfigViolation`] when a
|
|
/// configuration invariant was responsible.
|
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, KaptanError)]
|
|
pub enum ProtocolError {
|
|
/// The request target did not match this component.
|
|
#[kaptan_error(id = 2001)]
|
|
BadTarget,
|
|
/// The configuration lease or single transaction slot is occupied.
|
|
#[kaptan_error(id = 2002)]
|
|
SessionBusy,
|
|
/// The session is unknown, expired, or belongs to a different principal.
|
|
#[kaptan_error(id = 2003)]
|
|
InvalidSession,
|
|
/// Reusing one request ID with different content is forbidden.
|
|
#[kaptan_error(id = 2004)]
|
|
RequestConflict,
|
|
/// The request was not based on the current transaction revision.
|
|
#[kaptan_error(id = 2005)]
|
|
StaleRevision,
|
|
/// A command is invalid in the current lifecycle state.
|
|
#[kaptan_error(id = 2006)]
|
|
BadState,
|
|
/// The field is not present in this schema.
|
|
#[kaptan_error(id = 2007)]
|
|
UnknownField(FieldId),
|
|
/// A query requested an empty or out-of-range descriptor span.
|
|
#[kaptan_error(id = 2008)]
|
|
InvalidQuery,
|
|
/// The typed setter does not match the field descriptor.
|
|
#[kaptan_error(id = 2009)]
|
|
TypeMismatch(FieldId),
|
|
/// A local or complete validation issue.
|
|
#[kaptan_error(id = 2010)]
|
|
Violation(ConfigViolation),
|
|
/// Persistence failed after a complete validation pass.
|
|
#[kaptan_error(id = 2011)]
|
|
StorageFailure,
|
|
/// The adapter reached an impossible internal state.
|
|
#[kaptan_error(id = 2012)]
|
|
Internal,
|
|
}
|
|
|
|
/// Authoritative completion for one request.
|
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
pub struct ConfigReply {
|
|
/// Client request identity.
|
|
pub request_id: u32,
|
|
/// The current session, or zero when none exists.
|
|
pub session_id: u32,
|
|
/// The transaction revision, or zero when no transaction exists.
|
|
pub revision: u32,
|
|
/// Completed operation.
|
|
pub operation: Operation,
|
|
/// High-level result.
|
|
pub result: ResultKind,
|
|
/// Exact typed failure, if rejected.
|
|
pub error: Option<ProtocolError>,
|
|
/// Current lifecycle state after handling the request.
|
|
pub state: ConfigState,
|
|
}
|
|
|
|
impl ConfigReply {
|
|
/// Stable primary field for the wire response, or the reserved sentinel.
|
|
pub const fn primary_field(self) -> u16 {
|
|
match self.error {
|
|
Some(ProtocolError::Violation(violation)) => match violation.primary() {
|
|
Some(field) => field.get(),
|
|
None => u16::MAX,
|
|
},
|
|
Some(ProtocolError::UnknownField(field)) | Some(ProtocolError::TypeMismatch(field)) => {
|
|
field.get()
|
|
}
|
|
_ => u16::MAX,
|
|
}
|
|
}
|
|
|
|
/// Stable related field for the wire response, or the reserved sentinel.
|
|
pub const fn related_field(self) -> u16 {
|
|
match self.error {
|
|
Some(ProtocolError::Violation(violation)) => match violation.related_field() {
|
|
Some(field) => field.get(),
|
|
None => u16::MAX,
|
|
},
|
|
_ => u16::MAX,
|
|
}
|
|
}
|
|
|
|
/// Stable validation-rule code, or zero when no validation rule applies.
|
|
pub const fn validation_rule(self) -> u16 {
|
|
match self.error {
|
|
Some(ProtocolError::Violation(violation)) => violation.rule().code(),
|
|
_ => 0,
|
|
}
|
|
}
|
|
}
|