calternal_notes_core::canvas
Lossless Canvas files and bounded scene validation (DESIGN §60, #976).
This pure layer never writes a file. It retains source ranges, so an edit
changes only the Drawing and known text/link entries. Unknown Markdown,
JSON values, deleted elements and inline image bytes stay in the source.
Hosts must cap their read at MAX_FILE_BYTES + 1 before calling open.
Source: crates/calternal-notes-core/src/canvas.rs
Structs
Section titled “Structs”CanvasError
Section titled “CanvasError”pub struct CanvasError(pub &'static str);A content error has a fixed message; no User content enters logs.
Implements: Debug, Clone, PartialEq, Eq, std::fmt::Display, std::error::Error
Source: crates/calternal-notes-core/src/canvas.rs:20
CanvasFile
Section titled “CanvasFile”pub struct CanvasFileOne immutable opened file and its visible scene. Opening is never a save.
Implements: Debug
CanvasFile::open
Section titled “CanvasFile::open”pub fn open(source: &str) -> Result<Self>Open plain JSON or Markdown. All limits also run before every save.
CanvasFile::scene
Section titled “CanvasFile::scene”pub fn scene(&self) -> &ValueReturn the effective scene after Markdown text/link overrides.
CanvasFile::save
Section titled “CanvasFile::save”pub fn save(&self, scene: &Value) -> Result<String>Save an actual edit. A semantic no-op returns every original byte. Existing compressed Drawing blocks become plain JSON only on an edit.
Source: crates/calternal-notes-core/src/canvas.rs:38
Functions
Section titled “Functions”decode_event
Section titled “decode_event”pub fn decode_event(source: &str) -> Result<Value>Decode an event with the same duplicate-key and depth checks as a Drawing. Callers first enforce the smaller collaboration frame limit (#976).
Source: crates/calternal-notes-core/src/canvas.rs:210
file_reference
Section titled “file_reference”pub fn file_reference(element: &Value) -> Option<&Value>Portable Home-file reference, outside the binary files map (#989, §60).
Names are display/fallback names only; stable item identity wins on resolve.
Source: crates/calternal-notes-core/src/canvas.rs:711
is_canvas
Section titled “is_canvas”pub fn is_canvas(path: &str, source: &str) -> boolDetect a Canvas without changing its bytes (#976, DESIGN §60). The marker also supports imported Markdown whose filename has no suffix.
Source: crates/calternal-notes-core/src/canvas.rs:162
public_scene
Section titled “public_scene”pub fn public_scene(scene: &Value) -> Result<Value>Read-only public drawing projection (DESIGN §§54, 60, #991). Keep only drawing fields: unknown metadata, deleted content, links and assets never cross this boundary. Until #977 supplies per-viewer cards, every asset or card is a neutral rectangle, including its bound label. Source stays whole.
Source: crates/calternal-notes-core/src/canvas.rs:1396
searchable_text
Section titled “searchable_text”pub fn searchable_text(scene: &Value) -> Result<String>Project only visible Canvas text and source links, never JSON/image bytes. A deleted container also hides its bound text (security review #976).
Source: crates/calternal-notes-core/src/canvas.rs:170
valid_id
Section titled “valid_id”pub fn valid_id(id: &str) -> boolIDs from existing files are never renamed. New IDs use eight base62 chars.
Source: crates/calternal-notes-core/src/canvas.rs:215
valid_index
Section titled “valid_index”pub fn valid_index(index: &str) -> boolMatch rocicorp fractional-indexing’s base62 integer prefix and fraction. Bounds prevent a repeated insert-between operation growing an unbounded key.
Source: crates/calternal-notes-core/src/canvas.rs:237
valid_link
Section titled “valid_link”pub fn valid_link(link: &str) -> boolOnly safe navigation links are shared. No external resource is fetched.
Source: crates/calternal-notes-core/src/canvas.rs:225
validate_asset_bytes
Section titled “validate_asset_bytes”pub fn validate_asset_bytes(bytes: &[u8], mime: &str) -> Result<()>Validate Home assets and legacy images with one allowlist (#989, §60). Container terminators reject appended second formats. SVG stays passive; PDFs are downloadable files and only the thumbnail service renders them.
Source: crates/calternal-notes-core/src/canvas.rs:362
validate_element
Section titled “validate_element”pub fn validate_element(el: &Value) -> Result<()>Validate a whole element, retaining unknown fields under a small byte cap. Version and nonce are integers; the room resolves their ordering (#976).
Source: crates/calternal-notes-core/src/canvas.rs:542
validate_scene
Section titled “validate_scene”pub fn validate_scene(scene: &Value) -> Result<()>Validate geometry and aggregate work before a scene reaches a renderer. This also guards whole-element collaboration events, not just file opens.
Source: crates/calternal-notes-core/src/canvas.rs:256
Constants
Section titled “Constants”MAX_DEPTH
Section titled “MAX_DEPTH”pub const MAX_DEPTH: usizeRecursion stops before parsing or destroying a deeply nested JSON value.
Source: crates/calternal-notes-core/src/canvas.rs:16
MAX_ELEMENTS
Section titled “MAX_ELEMENTS”pub const MAX_ELEMENTS: usizeA large Canvas can contain the 5,000 elements in the §60 profile.
Source: crates/calternal-notes-core/src/canvas.rs:14
MAX_FILE_BYTES
Section titled “MAX_FILE_BYTES”pub const MAX_FILE_BYTES: usizeThe same cap applies to source, decompressed JSON and the saved file.