Skip to content

feat: Changes XML-related types to have owned and borrowed variants instead of being Cows. - #138

Merged
lukasfri merged 1 commit into
mainfrom
feat/owned-borrowed-types
Dec 25, 2025
Merged

feat: Changes XML-related types to have owned and borrowed variants instead of being Cows.#138
lukasfri merged 1 commit into
mainfrom
feat/owned-borrowed-types

Conversation

@lukasfri

@lukasfri lukasfri commented Oct 7, 2025

Copy link
Copy Markdown
Owner

This changes LocalName, QName, Prefix and XmlNamespace to have -Buf variants with slice types, instead of all being Cow-based. I've wanted to do this for a while, but haven't been bothered to do so until now.

Copilot AI review requested due to automatic review settings October 7, 2025 18:35

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR transitions XML-related types from using Cow-based ownership patterns to having dedicated owned (-Buf) and borrowed variants. This refactoring removes the lifetime parameters from the owned types and introduces a more explicit ownership model.

Key changes:

  • Introduces *Buf variants (e.g., LocalNameBuf, XmlNamespaceBuf, PrefixBuf, ExpandedNameBuf, QNameBuf) as owned counterparts to borrowed types
  • Removes Cow usage in favor of explicit owned/borrowed distinction
  • Updates all construction patterns from new() to from_str() for owned variants and new() for borrowed variants

Reviewed Changes

Copilot reviewed 26 out of 26 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
xmlity/src/lib.rs Core type definitions updated with *Buf variants and ownership model changes
xmlity/src/value/mod.rs Updated XmlElement and XmlAttribute to use *Buf variants
xmlity/src/value/serializer.rs Updated serialization infrastructure to use new type patterns
xmlity/src/value/serialize.rs Updated serialize implementations to use as_ref() for type conversion
xmlity/src/value/deserializer.rs Updated deserialization to use as_ref() for borrowed access
xmlity/src/value/deserialize.rs Updated context traits to use borrowed references
xmlity/src/ser.rs Updated serialization traits to use borrowed prefix references
xmlity/src/de.rs Updated deserialization context traits
xmlity/src/noop.rs Updated no-op serializer signatures
xmlity/src/macros.rs Updated macro generation to use new type construction patterns
xmlity/tests/*.rs Updated test code to use from_str() and *Buf variants
xmlity-quick-xml/src/*.rs Updated quick-xml integration for new type system
xmlity-quick-xml/tests/*.rs Updated integration tests
xmlity-quick-xml/examples/*.rs Updated examples
xmlity-derive/src/*.rs Updated derive macro implementations

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment thread xmlity/src/lib.rs Outdated
ExpandedName::new(
self.local_name.into_owned(),
self.namespace.map(|n| n.into_owned()),
// /// Converts this [`ExpandedName`] into an owned version.

Copilot AI Oct 7, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The commented-out documentation line should be uncommented since the method is active and public.

Suggested change
// /// Converts this [`ExpandedName`] into an owned version.
/// Converts this [`ExpandedName`] into an owned version.

Copilot uses AI. Check for mistakes.
Comment thread xmlity/src/lib.rs Outdated
Comment on lines 129 to 146
// /// Returns this [`ExpandedName`] as a reference.
// pub fn as_ref(&self) -> ExpandedName<'_> {
// ExpandedName::new(
// self.local_name.as_ref(),
// self.namespace.as_ref().map(|n| n.as_ref()),
// )
// }

/// Returns the local name of this [`ExpandedName`].
pub fn local_name(&self) -> &LocalName<'a> {
pub fn local_name(&self) -> &'a LocalName {
&self.local_name
}

/// Returns a mutable reference to the local name of this [`ExpandedName`].
pub fn local_name_mut(&mut self) -> &mut LocalName<'a> {
&mut self.local_name
}
// /// Returns a mutable reference to the local name of this [`ExpandedName`].
// pub fn local_name_mut(&mut self) -> &'a mut LocalName {
// &mut self.local_name
// }

Copilot AI Oct 7, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code should be removed instead of being commented out. If this functionality might be needed later, consider removing it and relying on version control history.

Copilot uses AI. Check for mistakes.
Comment thread xmlity/src/lib.rs Outdated
Comment on lines 129 to 156
// /// Returns this [`ExpandedName`] as a reference.
// pub fn as_ref(&self) -> ExpandedName<'_> {
// ExpandedName::new(
// self.local_name.as_ref(),
// self.namespace.as_ref().map(|n| n.as_ref()),
// )
// }

/// Returns the local name of this [`ExpandedName`].
pub fn local_name(&self) -> &LocalName<'a> {
pub fn local_name(&self) -> &'a LocalName {
&self.local_name
}

/// Returns a mutable reference to the local name of this [`ExpandedName`].
pub fn local_name_mut(&mut self) -> &mut LocalName<'a> {
&mut self.local_name
}
// /// Returns a mutable reference to the local name of this [`ExpandedName`].
// pub fn local_name_mut(&mut self) -> &'a mut LocalName {
// &mut self.local_name
// }

/// Returns the namespace of this [`ExpandedName`].
pub fn namespace(&self) -> &Option<XmlNamespace<'a>> {
pub fn namespace(&self) -> &Option<&'a XmlNamespace> {
&self.namespace
}

/// Returns a mutable reference to the namespace of this [`ExpandedName`].
pub fn namespace_mut(&mut self) -> &mut Option<XmlNamespace<'a>> {
&mut self.namespace
}
// /// Returns a mutable reference to the namespace of this [`ExpandedName`].
// pub fn namespace_mut(&mut self) -> &mut Option<XmlNamespace<'a>> {
// &mut self.namespace
// }

Copilot AI Oct 7, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code should be removed instead of being commented out. Consider removing commented-out methods to reduce code clutter.

Copilot uses AI. Check for mistakes.
Comment thread xmlity/src/lib.rs Outdated
Comment on lines 129 to 156
// /// Returns this [`ExpandedName`] as a reference.
// pub fn as_ref(&self) -> ExpandedName<'_> {
// ExpandedName::new(
// self.local_name.as_ref(),
// self.namespace.as_ref().map(|n| n.as_ref()),
// )
// }

/// Returns the local name of this [`ExpandedName`].
pub fn local_name(&self) -> &LocalName<'a> {
pub fn local_name(&self) -> &'a LocalName {
&self.local_name
}

/// Returns a mutable reference to the local name of this [`ExpandedName`].
pub fn local_name_mut(&mut self) -> &mut LocalName<'a> {
&mut self.local_name
}
// /// Returns a mutable reference to the local name of this [`ExpandedName`].
// pub fn local_name_mut(&mut self) -> &'a mut LocalName {
// &mut self.local_name
// }

/// Returns the namespace of this [`ExpandedName`].
pub fn namespace(&self) -> &Option<XmlNamespace<'a>> {
pub fn namespace(&self) -> &Option<&'a XmlNamespace> {
&self.namespace
}

/// Returns a mutable reference to the namespace of this [`ExpandedName`].
pub fn namespace_mut(&mut self) -> &mut Option<XmlNamespace<'a>> {
&mut self.namespace
}
// /// Returns a mutable reference to the namespace of this [`ExpandedName`].
// pub fn namespace_mut(&mut self) -> &mut Option<XmlNamespace<'a>> {
// &mut self.namespace
// }

Copilot AI Oct 7, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code should be removed instead of being commented out. Consider removing commented-out methods to reduce code clutter.

Copilot uses AI. Check for mistakes.
Comment thread xmlity/src/lib.rs Outdated
Comment on lines 368 to 377
// /// Converts this [`XmlNamespace`] into an owned version.
// pub fn into_owned(self) -> XmlNamespace<'static> {
// XmlNamespace(Cow::Owned(self.0.into_owned()))
// }

// /// Returns this [`XmlNamespace`] as a reference.
// pub fn as_ref(&self) -> XmlNamespace<'_> {
// XmlNamespace(Cow::Borrowed(&self.0))
// }

Copilot AI Oct 7, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code should be removed instead of being commented out. Consider removing commented-out methods to reduce code clutter.

Suggested change
// /// Converts this [`XmlNamespace`] into an owned version.
// pub fn into_owned(self) -> XmlNamespace<'static> {
// XmlNamespace(Cow::Owned(self.0.into_owned()))
// }
// /// Returns this [`XmlNamespace`] as a reference.
// pub fn as_ref(&self) -> XmlNamespace<'_> {
// XmlNamespace(Cow::Borrowed(&self.0))
// }

Copilot uses AI. Check for mistakes.
Comment thread xmlity/src/lib.rs Outdated
Comment on lines 492 to 514
// /// Converts this [`Prefix`] into an owned version.
// pub fn into_owned(self) -> Prefix<'static> {
// Prefix(Cow::Owned(self.0.into_owned()))
// }

// /// Returns this [`Prefix`] as a reference.
// pub fn as_ref(&self) -> Prefix<'_> {
// Prefix(Cow::Borrowed(&self.0))
// }

/// Returns this [`Prefix`] as a string slice.
pub fn as_str(&self) -> &str {
&self.0
}

/// Returns this [`Prefix`] as a [`QName`] with the `xmlns` prefix. This is useful for serializing namespaces.
pub fn xmlns(&'a self) -> QName<'a> {
QName::new(
Prefix::new("xmlns").expect("xmlns is a valid prefix"),
LocalName::from(self.clone()),
)
}
// /// Returns this [`Prefix`] as a [`QName`] with the `xmlns` prefix. This is useful for serializing namespaces.
// pub fn xmlns(&'a self) -> QName<'a> {
// QName::new(
// Prefix::new("xmlns").expect("xmlns is a valid prefix"),
// LocalName::from(self.clone()),
// )
// }

Copilot AI Oct 7, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code should be removed instead of being commented out. Consider removing commented-out methods to reduce code clutter.

Copilot uses AI. Check for mistakes.
Comment thread xmlity-quick-xml/src/de.rs Outdated
Comment on lines +206 to +212
// pub fn resolve_bytes_start<'a>(&'a self, bytes_start: &'a BytesStart<'a>) -> ExpandedName<'a> {
// self.resolve_qname(bytes_start.name(), false)
// }

pub fn resolve_attribute<'a>(&'a self, attribute: &'a Attribute<'a>) -> ExpandedName<'a> {
self.resolve_qname(attribute.key, true)
}
// pub fn resolve_attribute<'a>(&'a self, attribute: &'a Attribute<'a>) -> ExpandedName<'a> {
// self.resolve_qname(attribute.key, true)
// }

Copilot AI Oct 7, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code should be removed instead of being commented out. Consider removing commented-out methods to reduce code clutter.

Copilot uses AI. Check for mistakes.
Comment thread xmlity-quick-xml/src/de.rs Outdated
Comment on lines +206 to +212
// pub fn resolve_bytes_start<'a>(&'a self, bytes_start: &'a BytesStart<'a>) -> ExpandedName<'a> {
// self.resolve_qname(bytes_start.name(), false)
// }

pub fn resolve_attribute<'a>(&'a self, attribute: &'a Attribute<'a>) -> ExpandedName<'a> {
self.resolve_qname(attribute.key, true)
}
// pub fn resolve_attribute<'a>(&'a self, attribute: &'a Attribute<'a>) -> ExpandedName<'a> {
// self.resolve_qname(attribute.key, true)
// }

Copilot AI Oct 7, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dead code should be removed instead of being commented out. Consider removing commented-out methods to reduce code clutter.

Copilot uses AI. Check for mistakes.
@lukasfri
lukasfri force-pushed the feat/owned-borrowed-types branch from cb6b7e4 to 3ca5a91 Compare December 25, 2025 10:57

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 28 out of 28 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread xmlity/src/lib.rs
Comment on lines +327 to +329
pub fn new(value: &str) -> Result<&Self, XmlNamespaceParseError> {
//TODO: Validate URI
// SAFETY: The value has been validated.

Copilot AI Dec 25, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new method returns a Result but never actually returns an error because validation is not implemented (marked with TODO on line 328). The function should either implement proper URI validation or document clearly that validation is not yet implemented and all inputs are currently accepted. The SAFETY comment claiming "The value has been validated" is misleading when validation is not performed.

Suggested change
pub fn new(value: &str) -> Result<&Self, XmlNamespaceParseError> {
//TODO: Validate URI
// SAFETY: The value has been validated.
///
/// **Note:** URI validation is not yet implemented. At present, this
/// function accepts any input and always returns `Ok`, and the `Result`
/// return type is reserved for future validation logic.
pub fn new(value: &str) -> Result<&Self, XmlNamespaceParseError> {
// TODO: Implement URI validation. For now, all inputs are accepted.
// SAFETY: This currently calls `new_unchecked`, so correctness relies
// on the caller not relying on URI validation being performed here.

Copilot uses AI. Check for mistakes.
@lukasfri
lukasfri merged commit 18c8e2e into main Dec 25, 2025
12 checks passed
@lukasfri
lukasfri deleted the feat/owned-borrowed-types branch December 25, 2025 14:40
This was referenced Aug 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants