pub struct AnswerObservation {
pub observed_at: String,
pub source: String,
pub stale_after: Option<String>,
}Expand description
When the state behind an answer was read: the freshness contract of a capability answer.
Declared once and carried in the output type of every answer that is a picture of state, so that the output schema, OpenAPI, the MCP tool schemas and the command line’s JSON all carry it without a transport of their own. It is set where the state is read — the index build, the git read — never by the executor, which knows when a handler ran and not when the state it read was taken.
use std::time::{Duration, UNIX_EPOCH};
use majordomus_cli::index::AnswerObservation;
let at = UNIX_EPOCH + Duration::from_secs(1_788_000_000);
let o = AnswerObservation::taken("git read", at, Some(Duration::from_secs(120)));
assert_eq!(o.observed_at, "2026-08-29T10:40:00Z");
assert_eq!(o.stale_after.as_deref(), Some("2026-08-29T10:42:00Z"));
assert!(!o.is_stale_at(at + Duration::from_secs(120)));
assert!(o.is_stale_at(at + Duration::from_secs(121)));Fields§
§observed_at: StringRFC 3339 UTC, whole seconds: when the state behind the answer was read. Empty only in an answer from an index that was never built (a hand-made one in a test).
source: StringWhat was read at that time: index build or git read.
stale_after: Option<String>RFC 3339 UTC: after this the answer is not to be trusted as current even though nothing announced a change. Absent when there is no known blind spot.
Implementations§
Source§impl AnswerObservation
impl AnswerObservation
Sourcepub fn taken(source: &str, at: SystemTime, window: Option<Duration>) -> Self
pub fn taken(source: &str, at: SystemTime, window: Option<Duration>) -> Self
An observation of source taken at at, trusted for window when there is one.
use std::time::UNIX_EPOCH;
use majordomus_cli::index::AnswerObservation;
let o = AnswerObservation::taken("index build", UNIX_EPOCH, None);
assert_eq!((o.observed_at.as_str(), o.stale_after), ("1970-01-01T00:00:00Z", None));Sourcepub fn is_stale_at(&self, now: SystemTime) -> bool
pub fn is_stale_at(&self, now: SystemTime) -> bool
Whether now is past Self::stale_after. RFC 3339 UTC in whole seconds is fixed
width, so the comparison is of the strings.
use std::time::{Duration, UNIX_EPOCH};
use majordomus_cli::index::AnswerObservation;
let o = AnswerObservation::taken("git read", UNIX_EPOCH, None);
assert!(!o.is_stale_at(UNIX_EPOCH + Duration::from_secs(86_400)), "no window, never stale");Trait Implementations§
Source§impl Clone for AnswerObservation
impl Clone for AnswerObservation
Source§fn clone(&self) -> AnswerObservation
fn clone(&self) -> AnswerObservation
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for AnswerObservation
impl Debug for AnswerObservation
Source§impl Default for AnswerObservation
impl Default for AnswerObservation
Source§fn default() -> AnswerObservation
fn default() -> AnswerObservation
Source§impl<'de> Deserialize<'de> for AnswerObservation
impl<'de> Deserialize<'de> for AnswerObservation
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
impl Eq for AnswerObservation
Source§impl JsonSchema for AnswerObservation
impl JsonSchema for AnswerObservation
Source§fn schema_id() -> Cow<'static, str>
fn schema_id() -> Cow<'static, str>
Source§fn json_schema(generator: &mut SchemaGenerator) -> Schema
fn json_schema(generator: &mut SchemaGenerator) -> Schema
Source§fn inline_schema() -> bool
fn inline_schema() -> bool
$ref keyword. Read moreSource§impl PartialEq for AnswerObservation
impl PartialEq for AnswerObservation
Source§fn eq(&self, other: &AnswerObservation) -> bool
fn eq(&self, other: &AnswerObservation) -> bool
self and other values to be equal, and is used by ==.Source§impl Serialize for AnswerObservation
impl Serialize for AnswerObservation
impl StructuralPartialEq for AnswerObservation
Auto Trait Implementations§
impl Freeze for AnswerObservation
impl RefUnwindSafe for AnswerObservation
impl Send for AnswerObservation
impl Sync for AnswerObservation
impl Unpin for AnswerObservation
impl UnsafeUnpin for AnswerObservation
impl UnwindSafe for AnswerObservation
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.