pub struct Document {
pub frontmatter: Frontmatter,
pub body: String,
}Expand description
A parsed OKF concept document.
Fields§
§frontmatter: FrontmatterThe YAML frontmatter block (empty if the file had none).
body: StringEverything after the frontmatter.
Implementations§
Source§impl Document
impl Document
Sourcepub fn new(frontmatter: Frontmatter, body: impl Into<String>) -> Self
pub fn new(frontmatter: Frontmatter, body: impl Into<String>) -> Self
Creates a document from frontmatter and a body.
Sourcepub fn parse(text: &str) -> Result<Self, DocumentError>
pub fn parse(text: &str) -> Result<Self, DocumentError>
Parses a document from raw file text.
If the file does not begin with a --- frontmatter delimiter, the
entire text is treated as the body and the frontmatter is empty
(matching the reference parser). An opened-but-unclosed frontmatter
block is an error.
§Line endings
The two paths handle line endings the same way the reference implementation does, by deliberate parity:
- No frontmatter: the body is kept verbatim, so a file with CRLF
line endings round-trips byte-identically. This mirrors the
reference’s
return cls(frontmatter={}, body=text). - With frontmatter: the body is rebuilt via
lines().join("\n"), which normalizes\r\n(and a trailing\r) to\n. This mirrors the reference’stext.splitlines()+"\n".join(...). Anything inside the frontmatter block is likewise normalized before YAML parsing.
§Errors
Returns DocumentError::UnterminatedFrontmatter if the opening ---
has no matching close, DocumentError::InvalidYaml if the frontmatter
is not valid YAML, and DocumentError::FrontmatterNotMapping if it
parses to a scalar or sequence rather than a mapping.
Sourcepub fn serialize(&self) -> String
pub fn serialize(&self) -> String
Serializes the document back to text: frontmatter delimited by ---,
a blank line, then the body (terminated by a newline).
parse followed by serialize preserves frontmatter key order and the
body (modulo trailing-newline normalization), matching the reference.
Flow collections are re-emitted in block style, which is the same value
written differently.
Sourcepub fn validate(&self) -> Result<(), DocumentError>
pub fn validate(&self) -> Result<(), DocumentError>
Validates the document: the frontmatter must carry a
non-empty type, and nothing else is required.
That single check is the whole of document-level validation in v0.2, and
it matches the reference implementation’s OKFDocument.validate. Every
other field the spec describes is a SHOULD, so a concept carrying only
type passes here; see Document::missing_recommended for the
producer-side checklist and
validate_bundle (in the okf-validator crate) for the full diagnostics.
§Errors
Returns DocumentError::MissingKeys listing every required key that
is absent, empty, or has the wrong shape.
Sourcepub fn missing_recommended(&self) -> Vec<&'static str>
pub fn missing_recommended(&self) -> Vec<&'static str>
The recommended frontmatter keys this
document leaves unset, plus runtime when the concept is an Attested
Computation, which the spec requires it to carry.
None of these is a conformance failure, so Document::validate
ignores them: the spec forbids rejecting a concept for a missing optional
field. This is the checklist a producer wants before publishing, and
it is what validate_bundle (in the okf-validator crate) reports as
warnings. An empty result means the document is fully filled in.
generated counts as set when a legacy v0.1 timestamp stands in for
it, since consumers may read one for the other.
Sourcepub fn section(&self, heading: &str) -> Vec<&str>
pub fn section(&self, heading: &str) -> Vec<&str>
The non-blank lines under a top-level # heading in the body, up to the
next top-level heading.
The spec gives # Schema, # Examples, and # Computation conventional
meaning without attaching required behaviour, so this is the primitive a
consumer needs to read any of them. A port of the reference’s
_section_content_lines, including its details: heading is matched in
full (pass "# Schema"), only # counts as a heading so ##
subheadings stay inside the section, and each line keeps its original
indentation.
Returns an empty vector when no such section exists. A repeated heading contributes its lines to the same result.
Sourcepub fn footnote_refs(&self) -> Vec<FootnoteRef>
pub fn footnote_refs(&self) -> Vec<FootnoteRef>
Extracts the body’s [^label] attribution markers.
Sourcepub fn footnote_definitions(&self) -> Vec<FootnoteDef>
pub fn footnote_definitions(&self) -> Vec<FootnoteDef>
Extracts the body’s [^label]: text footnote definitions.
Sourcepub fn attributions(&self) -> Vec<Attribution>
pub fn attributions(&self) -> Vec<Attribution>
Joins the body’s footnotes to the sources entries they name, giving
per-claim attribution.
Labels that match no source are still returned, with
Attribution::source set to None.
Sourcepub fn inline_computation(&self) -> Option<InlineComputation>
pub fn inline_computation(&self) -> Option<InlineComputation>
The # Computation code block from the body, if there is one.
Sourcepub fn attested_computation(&self) -> Option<AttestedComputation>
pub fn attested_computation(&self) -> Option<AttestedComputation>
The Attested Computation contract: the computation frontmatter
resolved against the body’s # Computation block.
Returns None unless type is Attested Computation; call
AttestedComputation::from_parts directly to read the same keys off a
concept of another type.
Sourcepub fn citations(&self) -> Vec<Citation>
pub fn citations(&self) -> Vec<Citation>
Extracts numbered entries from a legacy v0.1 # Citations section.
v0.2 supersedes this with sources and footnote attribution;
Document::attributions is the v0.2 equivalent. Consumers MAY keep
reading # Citations for v0.1 documents.
Sourcepub fn has_legacy_citations(&self) -> bool
pub fn has_legacy_citations(&self) -> bool
true when the body carries a legacy # Citations section, which a
v0.2 producer should have migrated to sources.