use crate::generated::session_document::{self, SessionDocumentEffect, SessionDocumentError};
use crate::{SessionBuildState, SessionMetadata};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SessionDurableConfigAuthorityError {
message: String,
}
impl std::fmt::Display for SessionDurableConfigAuthorityError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.message)
}
}
impl std::error::Error for SessionDurableConfigAuthorityError {}
impl From<SessionDocumentError> for SessionDurableConfigAuthorityError {
fn from(inner: SessionDocumentError) -> Self {
Self {
message: inner.to_string(),
}
}
}
#[derive(Debug, Clone)]
pub struct AuthorizedSessionMetadata {
metadata: SessionMetadata,
}
impl AuthorizedSessionMetadata {
#[must_use]
pub fn into_metadata(self) -> SessionMetadata {
self.metadata
}
}
#[derive(Debug, Clone)]
pub struct AuthorizedSessionBuildState {
state: SessionBuildState,
}
impl AuthorizedSessionBuildState {
#[must_use]
pub fn into_state(self) -> SessionBuildState {
self.state
}
}
fn document_authority() -> session_document::SessionDocumentMachineAuthority {
session_document::SessionDocumentMachineAuthority::new()
}
fn drive_metadata_persist(
metadata: &SessionMetadata,
) -> Result<(), SessionDurableConfigAuthorityError> {
let mut authority = document_authority();
let effects = authority.authorize_session_metadata_persist(
u64::from(metadata.schema_version),
!metadata.model.trim().is_empty(),
)?;
expect_effect(&effects, |effect| {
matches!(
effect,
SessionDocumentEffect::SessionMetadataPersistAuthorized
)
})
}
fn drive_build_state_persist(
state: &SessionBuildState,
) -> Result<(), SessionDurableConfigAuthorityError> {
let mob_tool_authority_context_present = state.mob_tool_authority_context.is_some();
let mob_tool_authority_context_generated = state
.mob_tool_authority_context
.as_ref()
.is_some_and(|context| context.is_generated_authority_context());
let mut authority = document_authority();
let effects = authority.authorize_session_build_state_persist(
mob_tool_authority_context_present,
mob_tool_authority_context_generated,
)?;
expect_effect(&effects, |effect| {
matches!(
effect,
SessionDocumentEffect::SessionBuildStatePersistAuthorized
)
})
}
fn drive_build_state_restore() -> Result<(), SessionDurableConfigAuthorityError> {
let mut authority = document_authority();
let effects = authority.restore_session_build_state()?;
expect_effect(&effects, |effect| {
matches!(
effect,
SessionDocumentEffect::SessionBuildStateRestoreAuthorized
)
})
}
fn expect_effect(
effects: &[SessionDocumentEffect],
matches_expected: impl Fn(&SessionDocumentEffect) -> bool,
) -> Result<(), SessionDurableConfigAuthorityError> {
if !effects.is_empty() && effects.iter().all(matches_expected) {
Ok(())
} else {
Err(SessionDurableConfigAuthorityError {
message:
"generated session document authority emitted no durable-config authorization effect"
.to_string(),
})
}
}
pub fn authorize_session_metadata_persist(
mut metadata: SessionMetadata,
) -> Result<AuthorizedSessionMetadata, SessionDurableConfigAuthorityError> {
metadata.schema_version = crate::session_metadata_schema_version();
drive_metadata_persist(&metadata)?;
Ok(AuthorizedSessionMetadata { metadata })
}
pub fn restore_session_metadata(
metadata: SessionMetadata,
) -> Result<SessionMetadata, SessionDurableConfigAuthorityError> {
drive_metadata_persist(&metadata)?;
Ok(metadata)
}
pub fn authorize_session_build_state_persist(
state: SessionBuildState,
) -> Result<AuthorizedSessionBuildState, SessionDurableConfigAuthorityError> {
drive_build_state_persist(&state)?;
Ok(AuthorizedSessionBuildState { state })
}
pub fn restore_session_build_state(
state: SessionBuildState,
) -> Result<SessionBuildState, SessionDurableConfigAuthorityError> {
drive_build_state_restore()?;
Ok(state)
}