use core::fmt;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct RequestPolicySummary {
pub time_scale: &'static str,
pub observer: &'static str,
pub apparentness: &'static str,
pub frame: &'static str,
}
impl RequestPolicySummary {
pub const fn current() -> Self {
Self {
time_scale: super::CURRENT_TIME_SCALE_POLICY_SUMMARY_TEXT,
observer: super::CURRENT_OBSERVER_POLICY_SUMMARY_TEXT,
apparentness: super::CURRENT_APPARENTNESS_POLICY_SUMMARY_TEXT,
frame: super::CURRENT_FRAME_POLICY_SUMMARY_TEXT,
}
}
pub fn summary_line(&self) -> String {
format!(
"time-scale={}; observer={}; apparentness={}; frame={}",
self.time_scale, self.observer, self.apparentness, self.frame
)
}
pub fn validated_summary_line(&self) -> Result<String, RequestPolicySummaryValidationError> {
self.validate()?;
Ok(self.summary_line())
}
}
impl fmt::Display for RequestPolicySummary {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(&self.summary_line())
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum RequestPolicySummaryValidationError {
BlankField {
field: &'static str,
},
WhitespacePaddedField {
field: &'static str,
},
EmbeddedLineBreak {
field: &'static str,
},
FieldOutOfSync {
field: &'static str,
},
}
impl fmt::Display for RequestPolicySummaryValidationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::BlankField { field } => {
write!(f, "the request-policy summary field `{field}` is blank")
}
Self::WhitespacePaddedField { field } => write!(
f,
"the request-policy summary field `{field}` has surrounding whitespace"
),
Self::EmbeddedLineBreak { field } => write!(
f,
"the request-policy summary field `{field}` contains a line break"
),
Self::FieldOutOfSync { field } => write!(
f,
"the request-policy summary field `{field}` is out of sync with the current posture"
),
}
}
}
impl std::error::Error for RequestPolicySummaryValidationError {}
impl RequestPolicySummary {
pub fn validate(&self) -> Result<(), RequestPolicySummaryValidationError> {
let current = Self::current();
for (field, value, expected) in [
("time_scale", self.time_scale, current.time_scale),
("observer", self.observer, current.observer),
("apparentness", self.apparentness, current.apparentness),
("frame", self.frame, current.frame),
] {
if value.trim().is_empty() {
return Err(RequestPolicySummaryValidationError::BlankField { field });
}
if value.trim() != value {
return Err(RequestPolicySummaryValidationError::WhitespacePaddedField { field });
}
if value.contains('\n') || value.contains('\r') {
return Err(RequestPolicySummaryValidationError::EmbeddedLineBreak { field });
}
if value != expected {
return Err(RequestPolicySummaryValidationError::FieldOutOfSync { field });
}
}
Ok(())
}
}