From dd13cdfe8e057848813b412888818700734bc03f Mon Sep 17 00:00:00 2001 From: Imbris Date: Tue, 12 May 2026 15:11:47 -0400 Subject: [PATCH 1/4] Document new terminology that will be used for bauble objects and external assets --- OVERVIEW.md | 67 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 20 deletions(-) diff --git a/OVERVIEW.md b/OVERVIEW.md index bfc1678..6a5f288 100644 --- a/OVERVIEW.md +++ b/OVERVIEW.md @@ -5,7 +5,7 @@ In this way, Bauble is a format very useful for specifying information processed Once a context has been created, that context can then be used for parsing various Bauble source files and extracting the newly parsed data back as typed values that can be used to update the state of the program. -# BaubleContext +# `BaubleContext` [`BaubleContext`] is used to register various Bauble source files to parse information from, as well as maintaining a type registry where every known type to Bauble is provided. Through [`BaubleContext`], various separate Bauble source files are able to reference each other's objects. @@ -52,34 +52,62 @@ Whether the conversion is successful depends on the implementation of the [`Baub In order to support all Bauble values being parsed and represented as a single type in Rust, using type erasure is a possibility, however it has to be manually implemented. For example, a single `ErasedBauble` type which can represent any type that implements `Bauble`, but has to be explicitly downcast to the concrete type sometime later at runtime (when the type is known). -## Bauble overview +# Bauble overview -# Includes (use) +## Includes (use) All Bauble source files support the usage of `use`. Similar to Rust, it may include any item defined from a separate Bauble module, as long as both modules (the module being used, and the module using) exist within the same [`BaubleContext`]. Alternatively to `use`, like in Rust, the fully qualified path may be written out instead. `use` may be used to include both objects and Bauble registered types/traits. -# Object +## Object All bauble source files consists of a set of objets. A single Bauble object is a tree of Bauble values and a type. A Bauble object can be thought of as a single asset, being tied to a unique path. Objects are the format of its contents Bauble provides after it has parsed all of its files, and ultimately what is used to convery the parsed Bauble contents. -# Values +### Object terminology - A value in Bauble is typed, and contains an enum representing the kind of the value (whether it is a number, a string, an array or a map for example). +There are three kinds of Bauble objects. Top level, local, and inline. These can be seen +represented in the [`ObjectPath`] enum. + +A top level (or Top for short) object is the main kind of object. A single source file has a single +top level object which appears at the start of the file with the `0` identifier used as its name +(NOTE: completely empty files are also allowed). These objects have the same path as their +containing file. Top objects can be freely referenced by objects in other files. They can also be +referenced in the current file both by their full path and by the special `0` identifier. + +Local objects are the remaining named objects in a file that appear after the top object. They can +only be referenced by other objects in the same file and only via their name rather than a full +path. + +An inline object is a reference value within a Bauble object which is not written as a reference in +the source (see [References](#references)). Instead they appear as an "inlined" object directly +defined together with the object. Functionally, inline objects work similar to a regular reference +with the difference being they are defined locally to the object where they are used and are not +named separately referencable objects themselves. They act as a convenience for the alternative of +defining and referencing a separate object. The paths of these objects are generated based on the +parent object when loading a Bauble file. + +In addition to referencing other Bauble objects, external assets can be referenced. These assets +are registered via `BaubleContext::register_asset`. When an object references an external asset it +uses `ObjectPath::Top`. When something can be either a Bauble object or an external asset, we use +the term "asset". + +## Values + +A value in Bauble is typed, and contains an enum representing the kind of the value (whether it is a number, a string, an array or a map for example). Values are not that usually interacted with by the end user, as generally Bauble is implemented through the derive macro which means the user does not need to handle parsing from a raw Bauble value themselves. -# Types +## Types Types are registered to the [`BaubleContext`] through the builder, and every type requires the [`Bauble`] trait to be implemented on top of it. The [`Bauble`] trait determines how the type gets registered into the [`BaubleContext`], how it is parsed from Bauble source, and what path the type has. In Bauble every object is associated with a type, the type may be explicitly written with the value or implied by context, similar to type inference rules in Rust. -# Traits +## Traits Traits may be registered to Bauble in the form of `dyn Trait` types. If a trait has been registered, `dyn Trait` can then be used within registered Bauble types. In order for Bauble to parse a value of type `dyn Trait` with a value of a type that implements `Trait` called `T`, both `Trait` the `T` must be registered, and Bauble must know `T` implements `Trait`. @@ -88,11 +116,11 @@ Bauble is unable to use reflection and figure out if a type implements a trait b In order to register Bauble traits, you can use the method [`get_or_register_trait`](types::TypeRegistry::get_or_register_trait), then in order to mark a type as implementing that trait in Bauble, use [`add_trait_dependency`](types::TypeRegistry::add_trait_dependency) -# Modules +## Modules Every registered source file in Bauble is a module, similar to Rust. Every module contains various assets. The notion of sub-modules are not really present in Bauble. -# Paths +## Paths Every asset, module, reference and registered type/trait in Bauble has a corresponding unique path. In Bauble this is known as [`path::TypePath`], and is the association to that particular element in the [`BaubleContext`]. A path consists of various elements. Similar to Rust, most elements are seperated by `::`, so `a::b` means element `b` which is a child of element `a`. @@ -100,18 +128,17 @@ An element here can be a module, type or object. There are things known as sub-objects which may be appended to the path of a regular object, which are effectively children of the current object. A sub-object's path is denoted by `&$ty@$idx` where `$ty` is the index of the type of the sub-object and `$idx` is the index of the sub-object to the parent (the first sub-oject being 0, the second 1, the third 2, etc). -# References +## References -A reference is a Bauble object which may not be present in the current module. -A Bauble object's value may use a reference to avoid code duplication in the local file (referencing a previous object to use its values), or to reference the value of a Bauble object from a different file (module). +A reference is a value that points to another Bauble object or a registered external asset. +A Bauble object's value may use a reference to avoid code duplication in the local file +(referencing a previous object to use its values), or to reference the value of a Bauble object +from a different file (module). References are specified using a bauble `Path`. -Bauble does expose the builtin type for references, [`Ref`], which can be used for convenience to represent references from Bauble in Rust. -It is not required to use this type to represent references, custom types which are capable of parsing reference values are equal to the builtin [`Ref`] type, it is just a convenience. +Bauble does expose the builtin type for references, [`Ref`], which can be used for convenience to +represent references from Bauble in Rust. +It is not required to use this type to represent references, custom types which are capable of +parsing reference values are equal to the builtin [`Ref`] type, it is just a convenience. -# Sub-objects -A single Bauble object may contain sub-objects. -A sub-object is a reference value within a Bauble object which is not written as a reference, and rather as an "inlined" object directly defined together with the object. -Functionally sub-objects work similar to a regular reference with the difference being they are defined locally to the object where they are used and are not -top level objects themselves. From 03e2d60d18ac6414e2a850be5a11a79e3734209b Mon Sep 17 00:00:00 2001 From: Imbris Date: Wed, 13 May 2026 13:36:54 -0400 Subject: [PATCH 2/4] Replace uses of old bauble object terminology --- OVERVIEW.md | 25 +++++++++++++----- README.md | 2 +- bauble/src/context.rs | 15 ++++++----- bauble/src/object_path.rs | 8 +++--- bauble/src/parse/value.rs | 4 +-- bauble/src/types.rs | 10 ++++--- bauble/src/value/convert.rs | 12 ++++----- bauble/src/value/display.rs | 10 +++---- bauble/src/value/early_context.rs | 4 +-- bauble/src/value/error.rs | 8 +++--- bauble/src/value/mod.rs | 44 +++++++++++++++---------------- bauble/src/value/symbols.rs | 8 +++--- bauble/tests/integration.rs | 10 +++---- 13 files changed, 89 insertions(+), 71 deletions(-) diff --git a/OVERVIEW.md b/OVERVIEW.md index 6a5f288..5921cf2 100644 --- a/OVERVIEW.md +++ b/OVERVIEW.md @@ -118,15 +118,28 @@ use [`add_trait_dependency`](types::TypeRegistry::add_trait_dependency) ## Modules -Every registered source file in Bauble is a module, similar to Rust. Every module contains various assets. The notion of sub-modules are not really present in Bauble. +Every registered source file in Bauble is a module, similar to Rust. Every module contains various objects. The notion of sub-modules are not really present in Bauble. ## Paths -Every asset, module, reference and registered type/trait in Bauble has a corresponding unique path. In Bauble this is known as [`path::TypePath`], and is the association to that particular element in the [`BaubleContext`]. -A path consists of various elements. Similar to Rust, most elements are seperated by `::`, so `a::b` means element `b` which is a child of element `a`. -An element here can be a module, type or object. -There are things known as sub-objects which may be appended to the path of a regular object, which are effectively children of the current object. -A sub-object's path is denoted by `&$ty@$idx` where `$ty` is the index of the type of the sub-object and `$idx` is the index of the sub-object to the parent (the first sub-oject being 0, the second 1, the third 2, etc). +Every asset, module, reference and registered type/trait in Bauble has a corresponding unique path. +In Bauble this is known as [`path::TypePath`], and is the association to that particular element in +the [`BaubleContext`]. +A path consists of various elements. Similar to Rust, most elements are seperated by `::`, so +`a::b` means element `b` which is a child of element `a`. +An element here can be a module, type, object, or external asset. + +References to Objects use [`object_path::ObjectPath`] which is an enum that augments +[`path::TypePath`] with information about the kind of object. Note, local and inline objects are +not known to the `BaubleContext` so referring to top objects in the `BaubleContext` just uses +`TypePath`. + +There are objects known as inline objects which are effectively children of the current object. +Their paths are constructed by appending to the name of a regular object to create a new object +path with a different name that shares the same path prefix. +An inline object's path is denoted by `&$ty@$num` where `$ty` ID of the type of the +inline object and `$num` is an aribtrary number that distinguishes different inline objects with +the same parent (usually starting at 0). ## References diff --git a/README.md b/README.md index 4fc6cf9..e371c82 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Bauble has three steps in parsing. ## Examples of bauble ```rust -// bauble has the capability to use different types. Which are resolved by the `AssetCtx` +// bauble has the capability to use different types. Which are resolved by the `BaubleContext` use rpg::{Enemy, DamageType}; slime = Enemy { diff --git a/bauble/src/context.rs b/bauble/src/context.rs index e98bf14..c7edbb6 100644 --- a/bauble/src/context.rs +++ b/bauble/src/context.rs @@ -390,7 +390,7 @@ impl CtxNode { !node.is_empty() }); - // Top level assets match the path of their file (and all assets registered in + // Top level objects match the path of their file (and all objects registered in // BaubleContext are top level). self.reference.asset.take(); } @@ -605,13 +605,13 @@ impl BaubleContext { let mut early_ctx = crate::value::EarlyContext::new(self); - // Register assets paths from each successfully parsed file into the early context (before + // Register object paths from each successfully parsed file into the early context (before // types are known). for (file, values) in file_values.iter() { // Need a partial borrow here. let (path, _) = early_ctx.ctx.file(*file); let path = path.to_owned(); - crate::value::pre_register_assets(&mut early_ctx, path.borrow(), values); + crate::value::pre_register_objects(&mut early_ctx, path.borrow(), values); } let mut local_ctx = crate::local_context::LocalContext::new(); @@ -619,13 +619,13 @@ impl BaubleContext { let mut delayed = Vec::new(); let mut skip = Vec::new(); - // Then, register assets from each successfully parsed file into the context (while + // Then, register objects from each successfully parsed file into the context (while // resolving types). for (file, values) in file_values.iter() { // Need a partial borrow here. let (path, _) = early_ctx.ctx.file(*file); let path = path.to_owned(); - match crate::value::register_assets( + match crate::value::register_objects( &mut early_ctx, &mut local_ctx, path.borrow(), @@ -774,8 +774,9 @@ impl BaubleContext { /// Get all the assets starting from `path`, with an optional maximum depth of `max_depth`. /// - /// Inline objects are not registered as assets, they are exclusively visible in the list of - /// objects returned when loading/reloading files. + /// Only top level objects are registered as assets (in addition to external assets that are + /// manually registered for referencing by Bauble objects). Local and inline objects are + /// exclusively visible in the list of objects returned when loading/reloading files. pub fn assets( &self, path: TypePath<&str>, diff --git a/bauble/src/object_path.rs b/bauble/src/object_path.rs index cab7b33..3509273 100644 --- a/bauble/src/object_path.rs +++ b/bauble/src/object_path.rs @@ -1,4 +1,4 @@ -//! Bauble objects can either be top-level, local, or inline. +//! Bauble objects can either be top level, local, or inline. //! //! For a reference to an object, this is known once the full path to an //! object is resolved during value loading. That resolved path is represented using @@ -14,8 +14,8 @@ use crate::types::path::TypePath; use std::hash::{Hash, Hasher}; -/// Special cased identifier that is required and only allowed for the first asset in a file -/// (i.e. the top level asset that is named after the file). +/// Special cased identifier that is required and only allowed for the first object in a file +/// (i.e. the top level object that is named after the file). pub const TOP_LEVEL_IDENTIFIER: &str = "0"; /// Full path to a bauble object (or external asset). See [the module level documentation](self) @@ -39,7 +39,7 @@ pub const TOP_LEVEL_IDENTIFIER: &str = "0"; /// - `inline_ref` will be `ObjectPath::Inline("my_file::inline_ref&6@0") #[derive(Copy, Clone, Debug)] pub enum ObjectPath { - /// Top-level object or external asset. There is at most one per file. + /// Top level object or external asset. There is at most one per file. /// /// This shares the path of the containing file and uses the special identifier /// [`TOP_LEVEL_IDENTIFIER`]. diff --git a/bauble/src/parse/value.rs b/bauble/src/parse/value.rs index e90667c..873ec2a 100644 --- a/bauble/src/parse/value.rs +++ b/bauble/src/parse/value.rs @@ -179,14 +179,14 @@ pub struct Binding { #[derive(Debug, PartialEq, Eq, Hash)] pub enum BindingIdent { - /// This is the top level asset in a parsed file. + /// This is the top level object in a parsed file. /// /// It has the special cased identifier `0` and appears as the first item in the file. /// /// This holds no identifier string because it will have the same path as the file containing /// it. TopLevel(Spanned<()>), - /// This is a local asset. I.e. any additional assets in a parsed file. + /// This is a local object. I.e. any additional objects in a parsed file. Local(Ident), } diff --git a/bauble/src/types.rs b/bauble/src/types.rs index d592a86..9b444a8 100644 --- a/bauble/src/types.rs +++ b/bauble/src/types.rs @@ -607,8 +607,8 @@ impl TypeRegistry { // Check that instantiated objects match after being serialized to bauble text and // parsed. // - // Changes in sub-asset paths are specifically ignored, only the content of the - // sub-assets must match. + // Changes in inline object paths are specifically ignored, only the content of the + // inline objects must match. // dummy top level object let mut source = "0 = ()\n".to_string(); @@ -772,6 +772,7 @@ impl TypeRegistry { } } + // TODO: does this just apply to bauble objects or also external assets? /// Sets the trait all top-level assets are expected to have. By default this is the any trait. pub fn set_top_level_trait_dependency(&mut self, tr: TraitId) { self.top_level_trait_dependency = tr; @@ -1039,8 +1040,9 @@ pub type ValidationFunction = /// Function that creates a instance of the default value. Stored in [`TypeMeta`]. /// -/// * `&mut AdditionalUnspannedObjects` allows creating sub-assets if the new value needs to -/// reference sub-assets. +/// * `&mut AdditionalUnspannedObjects` allows creating objects if the new value needs to +/// reference additional objects (depending on configuration of the `AdditionalUnspannedObjects` +/// these can be created as inline objects or as new local objects). /// * `&TypeRegistry` allows calling [`TypeRegistry::instantiate`] to create new default instances /// of contained types and is used to get type information of contained types. /// * `TypeId` is the ID of the type. This allows the function to retrieve information about the diff --git a/bauble/src/value/convert.rs b/bauble/src/value/convert.rs index 8f7d0be..ea0f349 100644 --- a/bauble/src/value/convert.rs +++ b/bauble/src/value/convert.rs @@ -265,7 +265,7 @@ impl ConvertMeta<'_> { /// Represents additional objects added when parsing other objects. /// -/// Also known as sub-objects/sub-assets. +/// Also known as inline objects (previously known as sub-objects). pub(super) struct AdditionalObjects { objects: Vec, name_allocs: HashMap, @@ -407,13 +407,13 @@ impl<'a> AdditionalUnspannedObjects<'a> { /// Create a new instance with a custom closure to create unique names. /// - /// This allows creating the additional objects as objects that aren't sub-objects (aka inline - /// objects). + /// This allows creating the additional objects as objects that aren't inline objects (previously + /// known as sub-objects) /// /// The closure is passed the file path and the name of the parent object. The generated name /// should be joined to the provided file path. The parent object name can optionally use that - /// in its naming logic. Note, a number representing the type id of the current subobject may - /// be appended to the parent object name. + /// in its naming logic. Note, a number representing the type id of the object being named may + /// be appended to the provided parent object name. pub fn new_with_custom_namer( file_path: TypePath<&'a str>, object_name: TypePathElem<&'a str>, @@ -428,7 +428,7 @@ impl<'a> AdditionalUnspannedObjects<'a> { } /// Add the type id to the parent object name this keeps track of, for better unique names for - /// sub-objects. + /// inline objects. pub fn in_type( &mut self, ty: TypeId, diff --git a/bauble/src/value/display.rs b/bauble/src/value/display.rs index 670199e..ac63701 100644 --- a/bauble/src/value/display.rs +++ b/bauble/src/value/display.rs @@ -36,11 +36,11 @@ impl Default for DisplayConfig { /// /// # Main ways to call this /// -/// * `CTX` is [`TypeRegistry`] and `V` is `[[Object](Object)]`. Sub-objects in this slice will -/// only be displayed if they appear inline in other objects in the slice. +/// * `CTX` is [`TypeRegistry`] and `V` is `[[Object](Object)]`. Inline objects in this slice will +/// only be displayed if they are referenced in other objects in the slice. /// * `CTX` is `(&TypeRegistry, &[Object])` and `V` implements `IndentedDisplay>` (e.g. [`UnspannedVal`]). The provided slice of objects is necessary to display sub-objects -/// inline if `V` contains any. +/// V>>` (e.g. [`UnspannedVal`]). The provided slice of objects is necessary to display inline +/// objects if `V` contains any. pub fn display_formatted + ?Sized>( v: &V, ctx: &CTX, @@ -705,7 +705,7 @@ impl ValueCtx for ValueDisplayCtx<'_, UnspannedVal> { } /// IndentedDisplay impl where context includes slice of objects that contain any needed -/// sub-objects. +/// inline objects. impl<'b, V: ValueTrait + for<'a> IndentedDisplay>> IndentedDisplay<(&'b TypeRegistry, &'b [Object])> for V where diff --git a/bauble/src/value/early_context.rs b/bauble/src/value/early_context.rs index 2eb4ab6..0d8de7d 100644 --- a/bauble/src/value/early_context.rs +++ b/bauble/src/value/early_context.rs @@ -26,9 +26,9 @@ impl CombinedPathReference { /// 1. This mutates `self` in-place. /// 2. `Some` is allowed in matching fields if the contents are the same. /// - /// This is used to combine the [`EarlyPathReference`] obtained from pre-registered assets with + /// This is used to combine the [`EarlyPathReference`] obtained from pre-registered objects with /// the [`PathReference`] for existing items in [`BaubleContext`]. During the type resolution - /// process assets/modules will exist in both places as they are registered into + /// process objects/modules will exist in both places as they are registered into /// [`BaubleContext`]. /// /// Returns an error if there is a collision where matching fields both have `Some(_)` but they diff --git a/bauble/src/value/error.rs b/bauble/src/value/error.rs index 95f881a..205a70a 100644 --- a/bauble/src/value/error.rs +++ b/bauble/src/value/error.rs @@ -36,7 +36,7 @@ pub struct AmbiguousWithIdent { #[allow(missing_docs)] #[derive(Clone, Debug)] pub enum ConversionError { - UnregisteredAsset, + UnregisteredObject, UnresolvedType, MissingRequiredTrait { tr: types::TraitId, @@ -157,7 +157,7 @@ impl BaubleError for Spanned { "Expected the type `{}`", types.key_type(*expected).meta.path )), - ConversionError::UnregisteredAsset => Cow::Borrowed("Unregistered asset"), + ConversionError::UnregisteredObject => Cow::Borrowed("Unregistered object"), ConversionError::NotInstantiable { ty } => Cow::Owned(format!( "Can't construct a default value of the type {}", types.key_type(*ty).meta.path @@ -640,8 +640,8 @@ impl BaubleError for Spanned { Cow::Owned(s) } - ConversionError::UnregisteredAsset => Cow::Borrowed( - "This asset hasn't been registered with `BaubleContext::register_asset`", + ConversionError::UnregisteredObject => Cow::Borrowed( + "This object hasn't been registered with `BaubleContext::register_asset`", ), ConversionError::NotInstantiable { .. } => { Cow::Borrowed("Consider specifying this value manually") diff --git a/bauble/src/value/mod.rs b/bauble/src/value/mod.rs index 1e40605..3a28f02 100644 --- a/bauble/src/value/mod.rs +++ b/bauble/src/value/mod.rs @@ -553,7 +553,7 @@ impl std::fmt::Display for PathKind { } } -/// We can delay registering `Ref` assets if what they're referencing hasn't been loaded yet. +/// We delay registering `Ref` objects if what they're referencing hasn't been loaded yet. /// /// What they are referencing needs to be loaded in order to determine their type. #[derive(Debug)] @@ -695,11 +695,11 @@ pub(crate) fn resolve_delayed( } else { // We make sure that the referenced asset exists in the pre-registered // assets before producing `DelayedRegister`. So this error will only occur - // if the referenced asset's type failed to resolve (such that it wasn't + // if the referenced object's type failed to resolve (such that it wasn't // registered in resolve_delayed). errors.push( ConversionError::Custom(crate::CustomError::new(format!( - "{referenced_original} refers to an asset that failed to register", + "{referenced_original} refers to an object that failed to register", ))) .spanned(referenced_original.span), ); @@ -743,13 +743,13 @@ fn object_ident_path<'a>( (ident, path) } -/// Registers all new top level asset paths into [`EarlyContext`] so they will be known for -/// resolving full paths from `use`s in [`register_assets`]. +/// Registers all new top level object paths into [`EarlyContext`] so they will be known for +/// resolving full paths from `use`s in [`register_objects`]. /// /// We need to know what items brought into scope with `use` are assets rather than types or -/// modules to properly dertermine the full path (otherwise there could be multiple candidates +/// modules to properly determine the full path (otherwise there could be multiple candidates /// because items from different namespaces can have the same name). -pub(crate) fn pre_register_assets( +pub(crate) fn pre_register_objects( ctx: &mut EarlyContext<'_>, file_path: TypePath<&str>, values: &ParseValues, @@ -768,7 +768,7 @@ pub(crate) fn pre_register_assets( } } -pub(crate) fn register_assets( +pub(crate) fn register_objects( ctx: &mut EarlyContext<'_>, local_ctx: &mut crate::local_context::LocalContext, file_path: TypePath<&str>, @@ -785,7 +785,7 @@ pub(crate) fn register_assets( } } - // Add assets from this file to Symbols::use. + // Add objects from this file to Symbols::use. for ident in values.values.keys() { let span = ident.span(); let (ident, path) = object_ident_path(file_path, ident); @@ -812,10 +812,10 @@ pub(crate) fn register_assets( } } - // Resolve asset types and register the assets into `BaubleContext`. + // Resolve object types and register the objects into `BaubleContext`. // - // If the asset is a reference to another asset whose type is yet to be resolved, type - // resolution will be delayed by pushing an entry to `delayed`. These are then handled by + // If the object is a reference to an asset whose type is yet to be resolved, type resolution + // will be delayed by pushing an entry to `delayed`. These are then handled by // `resolve_delayed`. for (ident, binding) in &values.values { let span = ident.span(); @@ -859,9 +859,9 @@ pub(crate) fn register_assets( // already in `res` from calling `symbols.resolve_asset_type()` which uses // `resolve_path` internally. So there is no extra information from this error. // - // We use `resolve_asset` instead of just `resolve_path` because the asset should - // exist due to `pre_register_assets` or we will invevitably produce an error - // anyway, and the errors produced in register_assets are better than + // We use `resolve_asset` instead of just `resolve_path` because the object should + // exist due to `pre_register_objects` or we will invevitably produce an error + // anyway, and the errors produced in `register_objects` are better than // `resolve_delayed` because `symbols.uses` is available. && let Ok((maybe_ty, reference)) = symbols.resolve_asset(ref_path) { @@ -944,7 +944,7 @@ pub(crate) fn convert_values( let file_path = symbols.ctx.get_file_path(file); - // Add assets from this file to Symbols::use. + // Add objects from this file to Symbols::use. for ident in values.values.keys() { let span = ident.span(); let (ident, path) = object_ident_path(file_path, ident); @@ -957,7 +957,7 @@ pub(crate) fn convert_values( let Some((ty, path)) = asset else { // Didn't register assets. - errors.push(ConversionError::UnregisteredAsset.spanned(span)); + errors.push(ConversionError::UnregisteredObject.spanned(span)); continue; }; @@ -1045,12 +1045,12 @@ fn create_object( } } -/// Compare two objects and recursively compare their sub-objects (aka sub-assets) -/// while ignoring differences in the paths that refer to those sub-objects (instead -/// checking that the values in the sub-objects are indentical). +/// Compare two objects and recursively compare their inline objects while ignoring differences in +/// the paths that refer to those inline objects (instead checking that the values in the inline +/// objects are indentical). /// /// On error returns (original_val, loaded_val) for the objects that did not match. These may be a -/// pair of sub-objects rather than the top level objects. +/// pair of inline objects rather than the top level objects. fn compare_objects( original: &UnspannedVal, loaded: &UnspannedVal, @@ -1171,7 +1171,7 @@ pub struct CompareObjectsError { /// /// This is used to test that `Object`s content is preserved in a round-trip through the text format. /// -/// Ignores differences in the paths of sub-assets and only compares their content where they +/// Ignores differences in the paths of inline objects and only compares their content where they /// appear in the parent objects. pub fn compare_object_sets( original: impl Iterator>, diff --git a/bauble/src/value/symbols.rs b/bauble/src/value/symbols.rs index 2f26e7e..55219c6 100644 --- a/bauble/src/value/symbols.rs +++ b/bauble/src/value/symbols.rs @@ -157,7 +157,8 @@ impl From for ErrorPathReference { /// Representation of item names available in the current module. /// -/// There are multiple namespaces: types, assets (i.e. values defined in bauble), and modules. +/// There are multiple namespaces: types, assets (i.e. objects defined in bauble and external +/// registered assets), and modules. pub(crate) struct Symbols<'a> { /// Context for looking up things referenced by full path. pub(super) ctx: &'a BaubleContext, @@ -542,7 +543,8 @@ impl<'a> Symbols<'a> { /// /// This is used before types of assets are fully resolved. Afterwards, [`Symbols`] can be used. /// -/// There are multiple namespaces: types, assets (i.e. values defined in bauble), and modules. +/// There are multiple namespaces: types, assets (i.e. objects defined in bauble and external +/// registered assets), and modules. pub(crate) struct EarlySymbols<'a, 'b> { /// Context for looking up things referenced by full path. /// @@ -564,7 +566,7 @@ impl<'a, 'b> EarlySymbols<'a, 'b> { } } - /// Get contexts for registering new assets. + /// Get contexts for registering new objects. pub fn ctx_for_register(&mut self) -> (&mut BaubleContext, &mut LocalContext) { (self.ctx.ctx, self.local_ctx) } diff --git a/bauble/tests/integration.rs b/bauble/tests/integration.rs index d22114a..aaa38b4 100644 --- a/bauble/tests/integration.rs +++ b/bauble/tests/integration.rs @@ -591,7 +591,7 @@ pub fn ref_explicit_type_incorrect_multiple_files_ref_already_registered() { ); } -/// Test that local assets can not be referenced outside of the current file. +/// Test that local objects can not be referenced outside of the current file. #[test] #[should_panic = "Expected this path to refer to an asset"] pub fn ref_local_from_another_file() { @@ -783,7 +783,7 @@ fn name_matching_file_is_simplified() { ); } -// Note, this doesn't panic because local and top level asset paths can no longer collide. +// Note, this doesn't panic because local and top level object paths can no longer collide. #[test] fn duplicate_name_after_simplification() { let a = &TestFile::new( @@ -939,7 +939,7 @@ fn amiguous_ref_with_ident_multilayer() { &|ctx| { ctx.register_type::(); }, - // a and a_c_test will be delayed (they reference assets that aren't registered when they + // a and a_c_test will be delayed (they reference objects that aren't registered when they // are processed) // then a will be processed first (before a_c_test is registered) // we want to ensure an error is still produced in this case @@ -948,10 +948,10 @@ fn amiguous_ref_with_ident_multilayer() { ); } -/// Test for error message suggesting local asset. +/// Test for error message suggesting local object. #[test] #[should_panic = " Did you mean `test`?"] -fn local_asset_suggested() { +fn local_object_suggested() { let a = &test_file!( "a", "\n\ From 54e43841a44463e6743add6caf2191a0fabbc618 Mon Sep 17 00:00:00 2001 From: Imbris Date: Wed, 13 May 2026 13:44:00 -0400 Subject: [PATCH 3/4] Rename top_level_trait_dependency methods & field to better reflect that it isn't talking about top level objects/assets but rather the top level value inside an object. --- bauble/src/context.rs | 4 ++-- bauble/src/types.rs | 28 ++++++++++++++-------------- bauble/src/value/mod.rs | 4 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/bauble/src/context.rs b/bauble/src/context.rs index c7edbb6..c236fc3 100644 --- a/bauble/src/context.rs +++ b/bauble/src/context.rs @@ -133,9 +133,9 @@ impl BaubleContextBuilder { } #[allow(missing_docs)] - pub fn set_top_level_trait_requirement(&mut self) -> &mut Self { + pub fn set_object_trait_requirement(&mut self) -> &mut Self { let tr = self.registry.get_or_register_trait::(); - self.registry.set_top_level_trait_dependency(tr); + self.registry.set_object_trait_dependency(tr); self } diff --git a/bauble/src/types.rs b/bauble/src/types.rs index 9b444a8..4e9dc4f 100644 --- a/bauble/src/types.rs +++ b/bauble/src/types.rs @@ -115,7 +115,7 @@ pub struct TypeRegistry { type_from_rust: HashMap, to_be_assigned: HashSet, - top_level_trait_dependency: TraitId, + object_trait_dependency: TraitId, primitive_types: [TypeId; 5], } @@ -269,8 +269,8 @@ impl TypeRegistry { asset_refs: Default::default(), - // NOTE: Top level values always have to derive from this trait. - top_level_trait_dependency: Self::any_trait(), + // NOTE: Top level value in an object must always implement this trait. + object_trait_dependency: Self::any_trait(), to_be_assigned: Default::default(), @@ -304,14 +304,14 @@ impl TypeRegistry { this } - /// If a type implements the required top-level trait. - pub fn impls_top_level_trait(&self, id: TypeId) -> bool { - self.key_trait(self.top_level_trait_dependency).contains(id) + /// If a type implements the required trait for all objects. + pub fn impls_object_trait(&self, id: TypeId) -> bool { + self.key_trait(self.object_trait_dependency).contains(id) } - /// The trait that's expected for all top-level bauble assets to have. - pub fn top_level_trait(&self) -> TraitId { - self.top_level_trait_dependency + /// The trait that's expected for all bauble objects to have. + pub fn object_trait(&self) -> TraitId { + self.object_trait_dependency } /// This is present in all `TypeRegistry` @@ -574,7 +574,7 @@ impl TypeRegistry { // If the path is not writable then it cannot be validated // as it cannot be written out as Bauble source. || !ty.meta.path.is_representable_type() - || !ty.meta.traits.contains(&self.top_level_trait_dependency) + || !ty.meta.traits.contains(&self.object_trait_dependency) { continue; } @@ -772,10 +772,10 @@ impl TypeRegistry { } } - // TODO: does this just apply to bauble objects or also external assets? - /// Sets the trait all top-level assets are expected to have. By default this is the any trait. - pub fn set_top_level_trait_dependency(&mut self, tr: TraitId) { - self.top_level_trait_dependency = tr; + /// Sets the trait all types used for objects are expected to have. By default this is the any + /// trait. + pub fn set_object_trait_dependency(&mut self, tr: TraitId) { + self.object_trait_dependency = tr; } /// Registers `ty` as implementing `tr`. diff --git a/bauble/src/value/mod.rs b/bauble/src/value/mod.rs index 3a28f02..d53096c 100644 --- a/bauble/src/value/mod.rs +++ b/bauble/src/value/mod.rs @@ -1034,11 +1034,11 @@ fn create_object( value: Val, type_registry: &TypeRegistry, ) -> Result { - if type_registry.impls_top_level_trait(*value.ty) { + if type_registry.impls_object_trait(*value.ty) { Ok(Object { object_path, value }) } else { Err(ConversionError::MissingRequiredTrait { - tr: type_registry.top_level_trait(), + tr: type_registry.object_trait(), ty: *value.ty, } .spanned(value.span())) From b2801a0591b0d5f6d92aa24c39347544a5aed77f Mon Sep 17 00:00:00 2001 From: Imbris Date: Fri, 15 May 2026 12:04:57 -0400 Subject: [PATCH 4/4] Clarify what external assets are --- OVERVIEW.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/OVERVIEW.md b/OVERVIEW.md index 5921cf2..972286f 100644 --- a/OVERVIEW.md +++ b/OVERVIEW.md @@ -91,10 +91,11 @@ named separately referencable objects themselves. They act as a convenience for defining and referencing a separate object. The paths of these objects are generated based on the parent object when loading a Bauble file. -In addition to referencing other Bauble objects, external assets can be referenced. These assets -are registered via `BaubleContext::register_asset`. When an object references an external asset it -uses `ObjectPath::Top`. When something can be either a Bauble object or an external asset, we use -the term "asset". +In addition to referencing other Bauble objects, external assets can be referenced. These are +assets that aren't bauble files. For example, an audio or image asset. They can be exposed to be +referenced by bauble values via `BaubleContext::register_asset`. When an object references an +external asset it uses `ObjectPath::Top` wrapping the path provided to `register_asset `. When +something can be either a Bauble object or an external asset, we use the term "asset". ## Values