///|
/// A failure to construct metadata from a non-object JSON value.
pub(all) suberror MetadataError {
/// Metadata must be a JSON object, including when empty.
ExpectedObject
} derive(Eq, Debug)
///|
pub extend MetadataError with Eq::{equal, not_equal}
///|
pub extend MetadataError with @debug.Debug::{to_repr}
///|
/// Immutable attributes belonging to one notebook node. Construction and
/// exports deep-copy JSON so nested mutable values cannot change metadata.
/// Format-specific constructors validate the meaning of reserved keys.
struct Metadata {
fields : Map[String, Json]
} derive(Eq, Debug)
///|
pub extend Metadata with Eq::{equal, not_equal}
///|
pub extend Metadata with @debug.Debug::{to_repr}
///|
fn copy_metadata_json(value : Json) -> Json {
match value {
Object(fields) => Json(fields.map((_, value) => copy_metadata_json(value)))
Array(items) => Json(items.map(copy_metadata_json))
_ => value
}
}
///|
/// Require a JSON object and copy its entire value graph. Raise ExpectedObject
/// for any other JSON type. Custom keys and JSON values are retained.
pub fn Metadata::Metadata(value : Json) -> Metadata raise MetadataError {
guard copy_metadata_json(value) is Object(fields) else {
raise ExpectedObject
}
{ fields, }
}
///|
/// Create an empty metadata container without a fallible JSON conversion.
pub fn Metadata::empty() -> Metadata {
{ fields: {}, }
}
///|
/// Look up an exact key, returning an independent JSON value or None.
/// A present JSON null is Some(Null), distinct from an absent key.
pub fn Metadata::get(self : Metadata, key : String) -> Json? {
self.fields.get(key).map(copy_metadata_json)
}
///|
/// Return immutable keys without a sorting guarantee.
pub fn Metadata::keys(self : Metadata) -> ReadOnlyArray[String] {
ReadOnlyArray::from_iter(self.fields.keys())
}
///|
/// Return whether this available metadata container has no attributes.
pub fn Metadata::is_empty(self : Metadata) -> Bool {
self.fields.is_empty()
}
///|
/// Export an independent JSON object that callers may mutate safely.
pub fn Metadata::to_json(self : Metadata) -> Json {
copy_metadata_json(Json(self.fields))
}