diff --git a/packages/cli/src/elements_metadata.rs b/packages/cli/src/elements_metadata.rs new file mode 100644 index 0000000000..cb666e08ed --- /dev/null +++ b/packages/cli/src/elements_metadata.rs @@ -0,0 +1,37 @@ +use manganis_core::linker::LinkSection; +use manganis_core::BundledMetadata; +use object::{read::archive::ArchiveFile, File as ObjectFile, Object, ObjectSection}; +use serde::{Deserialize, Serialize}; + +/// Fill this manifest with whatever tables might come from the object file +fn collect_elements_metadata(&mut self, obj: &ObjectFile) -> anyhow::Result> { + for section in obj.sections() { + let Ok(section_name) = section.name() else { + continue; + }; + + // Check if the link section matches the asset section for one of the platforms we support. This may not be the current platform if the user is cross compiling + let matches = LinkSection::ALL + .iter() + .any(|x| x.link_section == section_name); + + if !matches { + continue; + } + + let bytes = section + .uncompressed_data() + .context("Could not read uncompressed data from object file")?; + + let mut buffer = const_serialize::ConstReadBuffer::new(&bytes); + while let Some((remaining_buffer, asset)) = + const_serialize::deserialize_const!(BundledMetadata, buffer) + { + self.assets + .insert(asset.absolute_source_path().into(), asset); + buffer = remaining_buffer; + } + } + + Ok(()) +} diff --git a/packages/core-types/src/attributes.rs b/packages/core-types/src/attributes.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/core-types/src/elements.rs b/packages/core-types/src/elements.rs new file mode 100644 index 0000000000..a49e89e9ab --- /dev/null +++ b/packages/core-types/src/elements.rs @@ -0,0 +1,61 @@ +use serde::{Serialize, Deserialize} + +/// the attribute specification, to be used with `manganis::register_element!` +#[derive(Serialize, Deserialize)] +pub struct AttributeSpecification { + /// the name of the attribute. + /// This is not the rust name: if this attribute has name `type`, + /// it will be used as `rsx!{ element { r#type = ... } }` + name: Option<&'static str>, + namespace: Option<&'static str>, +} + + +/// the element specification, to be used with `manganis::register_element!` +/// Example: +/// ```rust +/// manganis::register_elemenent!( +/// ElementSpecification { +/// name: "my_div", +/// namespace: None, +/// attribute_group: Some("html_element"), +/// special_attributes: &[ +/// AttributeSpecification {name: "fancy_color", namespace: None} +/// ] +/// } +/// ) +/// ``` +/// make sur that the name of the attribute group you use is defined in a library you included in +/// your app. +pub struct ElementSpecification { + /// the name of the element. + /// This is not the rust name: if this attribute has name `await`, + /// it will be used as `rsx!{ r#await { ... } }` + name: &'static, + namespace: Option<&'static str>, + /// the optional attribute group, like `html_element` or `svg_element`. + attribute_group: Option<&'static str>, + /// the attributes that are not included in the attribute group. + special_attributes: &'static [AttributeSpecification], +} + +/// the attribute group specification, to be used with `manganis::register_element!` +/// Example: +/// ```rust +/// manganis::register_attribute_group!( +/// AttributeGroupSpecification { +/// name: "my_div", +/// attributes: &[ +/// AttributeSpecification {name: "fancy_color", namespace: None} +/// ] +/// } +/// ) +/// ``` +/// make sur that the name of the attribute group you use is defined in a library you included in +/// your app. +pub struct AttributeGroupSpecification { + /// the identifier of this attribute group + name: &'static str, + /// + attributes: &'static [AttributeSpecification], +} diff --git a/packages/core-types/src/lib.rs b/packages/core-types/src/lib.rs index 0aa2cfcf96..60cf4bb354 100644 --- a/packages/core-types/src/lib.rs +++ b/packages/core-types/src/lib.rs @@ -2,8 +2,10 @@ pub mod bubbles; pub mod bundled; pub mod formatter; pub mod hr_context; +pub mod elements; pub use bubbles::*; pub use bundled::*; pub use formatter::*; pub use hr_context::*; +pub use elements::*; diff --git a/packages/manganis/manganis-core/src/lib.rs b/packages/manganis/manganis-core/src/lib.rs index b3dddf836b..1d7b148e4b 100644 --- a/packages/manganis/manganis-core/src/lib.rs +++ b/packages/manganis/manganis-core/src/lib.rs @@ -16,4 +16,7 @@ pub use js::*; mod asset; pub use asset::*; +mod metadata; +pub use metadata::*; + pub mod linker; diff --git a/packages/manganis/manganis-core/src/metadata.rs b/packages/manganis/manganis-core/src/metadata.rs new file mode 100644 index 0000000000..7e3e44f5d4 --- /dev/null +++ b/packages/manganis/manganis-core/src/metadata.rs @@ -0,0 +1,59 @@ +use const_serialize::{ConstStr, SerializeConst}; + +#[derive( + Debug, + PartialEq, + PartialOrd, + Clone, + Copy, + Hash, + SerializeConst, + serde::Serialize, + serde::Deserialize, +)] +pub struct BundledMetadata { + pub key: ConstStr, + pub value: ConstStr, +} + +impl BundledMetadata { + #[doc(hidden)] + /// This should only be called from the macro + /// Create a new metadata + pub const fn new( + key: &'static str, + value: &'static str, + ) -> Self { + Self { + key: ConstStr::new(key), + value: ConstStr::new(value), + } + } +} + +#[derive(Debug, PartialEq, Clone, Copy)] +pub struct Metadata { + /// The bundled metadata + bundled: BundledMetadata, + /// The link section for the metadata + keep_link_section: fn() -> u8, +} + + + +impl Metadata { + #[doc(hidden)] + /// This should only be called from the macro + /// Create a new metadata + pub const fn new(bundled: BundledMetadata, keep_link_section: fn() -> u8) -> Self { + Self { + bundled, + keep_link_section, + } + } + + /// Get the bundled metadata + pub const fn bundled(&self) -> &BundledMetadata { + &self.bundled + } +} diff --git a/packages/manganis/manganis-macro/src/lib.rs b/packages/manganis/manganis-macro/src/lib.rs index 078b137ca2..0c703344fb 100644 --- a/packages/manganis/manganis-macro/src/lib.rs +++ b/packages/manganis/manganis-macro/src/lib.rs @@ -6,6 +6,7 @@ use quote::{quote, ToTokens}; use syn::parse_macro_input; pub(crate) mod asset; +pub(crate) mod metadata; pub(crate) mod linker; use linker::generate_link_section; diff --git a/packages/manganis/manganis-macro/src/metadata.rs b/packages/manganis/manganis-macro/src/metadata.rs new file mode 100644 index 0000000000..70b786d12e --- /dev/null +++ b/packages/manganis/manganis-macro/src/metadata.rs @@ -0,0 +1 @@ +// TODO