Skip to main content

Document

Struct Document 

Source
pub struct Document { /* private fields */ }
Expand description

A fully-parsed Quillmark document. Serde routes through StoredDocument; for the plate wire shape see Document::to_plate_json.

Implementations§

Source§

impl Document

Source

pub fn set_quill_ref(&mut self, reference: QuillReference)

Source

pub fn card_mut(&mut self, index: usize) -> Option<&mut Card>

Source

pub fn push_card(&mut self, card: Card) -> Result<(), EditError>

Append a composable card. Its $kind must be a valid, non-reserved composable kind (EditError::InvalidKindName / EditError::ReservedKind otherwise) — the invariant for any card in the cards list, enforced here so every entry path shares it.

Source

pub fn insert_card(&mut self, index: usize, card: Card) -> Result<(), EditError>

Insert a composable card at index (index > lenEditError::IndexOutOfRange; invalid $kindEditError::InvalidKindName / EditError::ReservedKind).

Source

pub fn remove_card(&mut self, index: usize) -> Option<Card>

Source

pub fn set_card_kind( &mut self, index: usize, new_kind: impl Into<String>, ) -> Result<(), EditError>

Replace the $kind of the composable card at index.

Only the $kind metadata changes; the payload and body are untouched (field-bag semantics). Old-schema fields linger in the bag; new-schema fields are absent until set explicitly. Schema migration is the caller’s responsibility — this is a structural primitive.

Returns EditError::IndexOutOfRange, EditError::InvalidKindName, or EditError::ReservedKind on constraint violations.

Source

pub fn move_card(&mut self, from: usize, to: usize) -> Result<(), EditError>

Move card at from to position to. No-op when from == to. Either index out of range → EditError::IndexOutOfRange.

Source§

impl Document

Source

pub fn to_markdown(&self) -> String

Emit canonical Quillmark Markdown from this document.

§Contract
  1. Type-fidelity round-trip. Document::from_markdown(&doc.to_markdown()) returns a Document equal to doc by value and by type variant. QuillValue::String("on") round-trips as a string, never as a bool. QuillValue::String("01234") round-trips as a string, never as an integer. This guarantee is the whole point of owning emission.

  2. Emit-idempotent. to_markdown is a pure function of doc; two calls on the same doc return byte-equal strings.

Byte-equality with the original source is not guaranteed.

§Emission rules (§5.2)
  • Line endings: \n only. CRLF normalization happens on import.
  • Every block is emitted as a ~~~ card-yaml fence: a bare ~~~ opener, the $-prefixed system-metadata lines ($quill: <ref> for the root block, $kind: <kind> for composable cards) leading the YAML payload, the user-defined data fields, then a closing ~~~.
  • Cards: one blank line before each, then the block, then the card body.
  • Body: emitted verbatim after the root block (and after each card).
  • Mappings and sequences: block style at every nesting level.
  • Scalars (booleans, null, numbers, strings): delegated to serde-saphyr, which emits the type-canonical form (true/ false, null, bare numeric literal) and quotes strings only when the unquoted form would be misread (on/yes/off, null/~, numeric-looking strings, leading flow indicators, : runs, …). Quoting form is not stable — what matters is that the emitted scalar round-trips to the same QuillValue variant. This is the type-fidelity guarantee.
  • Multi-line strings: emitted as inline double-quoted scalars with \n escapes; no | / > block forms.
§Open decisions (resolved)
  • Nested-map order. QuillValue is backed by serde_json::Value whose object type (serde_json::Map) preserves insertion order when the serde_json/preserve_order feature is enabled (it is in this workspace). Insertion order is therefore preserved for nested maps at emit time.

  • Empty containers.

    • Empty object ({}) → the key is omitted from emit entirely.
    • Empty array ([]) → emitted as key: []\n.
§What is preserved
  • YAML comments: own-line and inline trailing comments round-trip at their source position. Comments whose host disappears at emit time (empty-mapping omission, programmatic field removal) degrade to own-line comments at the same indent so the comment text is preserved even when its position shifts.
  • !must_fill tags: round-trip via the fill flag on PayloadItem::Field.
§What is lost
  • Other custom tags (!include, !env, …): the tag is dropped; the scalar value is preserved.
  • Original quoting style: strings are re-emitted in saphyr’s canonical form (plain when safe, quoted when ambiguous). The form chosen for emit may not match the form in the source.
Source§

impl Document

Source

pub fn from_main_and_cards( main: Card, cards: Vec<Card>, warnings: Vec<Diagnostic>, ) -> Self

Create a Document from a pre-built main card and composable cards. main must carry $quill; composable cards must not.

Source

pub fn from_markdown(markdown: &str) -> Result<Self, ParseError>

Source

pub fn from_markdown_with_warnings( markdown: &str, ) -> Result<ParseOutput, ParseError>

Source

pub fn main(&self) -> &Card

Source

pub fn main_mut(&mut self) -> &mut Card

Source

pub fn quill_reference(&self) -> QuillReference

The $quill reference from the root block. Always present on parsed documents.

Source

pub fn cards(&self) -> &[Card]

Source

pub fn cards_mut(&mut self) -> &mut [Card]

Source

pub fn warnings(&self) -> &[Diagnostic]

Non-fatal warnings from the parse; empty for programmatically built documents.

Source

pub fn to_plate_json(&self) -> Value

Serialize to the JSON wire shape consumed by backend plates. This is the only place in quillmark-core that produces this shape:

{
  "$quill": "<ref>",
  "$body": "<global-body>",
  "$cards": [{ "$kind": "<tag>", "$body": "<card-body>", "<field>": <value>, ... }],
  "<field>": <value>, ...
}

$-prefixed keys carry document-level metadata (quill ref, body text, card list, card kind). User payload fields stay flat at the root — they cannot collide with $ keys because user field names are never $-prefixed (they match [A-Za-z_][A-Za-z0-9_]*).

Trait Implementations§

Source§

impl Clone for Document

Source§

fn clone(&self) -> Document

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Document

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for Document

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl From<&Document> for DocumentV0_92_0

Source§

fn from(doc: &Document) -> Self

Converts to this type from the input type.
Source§

impl From<Document> for StoredDocument

Source§

fn from(doc: Document) -> Self

Converts to this type from the input type.
Source§

impl PartialEq for Document

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for Document

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl TryFrom<DocumentV0_92_0> for Document

Source§

type Error = StorageError

The type returned in the event of a conversion error.
Source§

fn try_from(payload: DocumentV0_92_0) -> Result<Self, Self::Error>

Performs the conversion.
Source§

impl TryFrom<StoredDocument> for Document

Source§

type Error = StorageError

The type returned in the event of a conversion error.
Source§

fn try_from(stored: StoredDocument) -> Result<Self, Self::Error>

Performs the conversion.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.