From f5996ffb9e4d630043d1d15fbb9e13baf178f30d Mon Sep 17 00:00:00 2001 From: Mingun Date: Sat, 15 Jun 2024 22:45:58 +0500 Subject: [PATCH 1/2] Move helper functions to the `utils` mod and test them is_whitespace is trivial therefore not tested Also make `name_len` function `const` --- src/events/attributes.rs | 4 +- src/events/mod.rs | 37 +------------- src/reader/async_tokio.rs | 4 +- src/reader/buffered_reader.rs | 3 +- src/reader/mod.rs | 17 +------ src/reader/slice_reader.rs | 3 +- src/reader/state.rs | 3 +- src/utils.rs | 96 +++++++++++++++++++++++++++++++++++ 8 files changed, 109 insertions(+), 58 deletions(-) diff --git a/src/events/attributes.rs b/src/events/attributes.rs index e08303d7..3d5ca059 100644 --- a/src/events/attributes.rs +++ b/src/events/attributes.rs @@ -5,8 +5,8 @@ use crate::errors::Result as XmlResult; use crate::escape::{escape, resolve_predefined_entity, unescape_with}; use crate::name::QName; -use crate::reader::{is_whitespace, Reader}; -use crate::utils::{write_byte_string, write_cow_string, Bytes}; +use crate::reader::Reader; +use crate::utils::{is_whitespace, write_byte_string, write_cow_string, Bytes}; use std::fmt::{self, Debug, Display, Formatter}; use std::iter::FusedIterator; use std::{borrow::Cow, ops::Range}; diff --git a/src/events/mod.rs b/src/events/mod.rs index 593804d1..a5009ba4 100644 --- a/src/events/mod.rs +++ b/src/events/mod.rs @@ -41,6 +41,7 @@ pub mod attributes; use encoding_rs::Encoding; use std::borrow::Cow; use std::fmt::{self, Debug, Formatter}; +use std::mem::replace; use std::ops::Deref; use std::str::from_utf8; @@ -50,12 +51,10 @@ use crate::escape::{ escape, minimal_escape, partial_escape, resolve_predefined_entity, unescape_with, }; use crate::name::{LocalName, QName}; -use crate::reader::{is_whitespace, name_len}; -use crate::utils::write_cow_string; #[cfg(feature = "serialize")] use crate::utils::CowRef; +use crate::utils::{name_len, trim_xml_end, trim_xml_start, write_cow_string}; use attributes::{Attribute, Attributes}; -use std::mem::replace; /// Opening tag data (`Event::Start`), with optional attributes. /// @@ -1257,38 +1256,6 @@ fn str_cow_to_bytes<'a, C: Into>>(content: C) -> Cow<'a, [u8]> { } } -/// Returns a byte slice with leading XML whitespace bytes removed. -/// -/// 'Whitespace' refers to the definition used by [`is_whitespace`]. -const fn trim_xml_start(mut bytes: &[u8]) -> &[u8] { - // Note: A pattern matching based approach (instead of indexing) allows - // making the function const. - while let [first, rest @ ..] = bytes { - if is_whitespace(*first) { - bytes = rest; - } else { - break; - } - } - bytes -} - -/// Returns a byte slice with trailing XML whitespace bytes removed. -/// -/// 'Whitespace' refers to the definition used by [`is_whitespace`]. -const fn trim_xml_end(mut bytes: &[u8]) -> &[u8] { - // Note: A pattern matching based approach (instead of indexing) allows - // making the function const. - while let [rest @ .., last] = bytes { - if is_whitespace(*last) { - bytes = rest; - } else { - break; - } - } - bytes -} - fn trim_cow<'a, F>(value: Cow<'a, [u8]>, trim: F) -> Cow<'a, [u8]> where F: FnOnce(&[u8]) -> &[u8], diff --git a/src/reader/async_tokio.rs b/src/reader/async_tokio.rs index 19ca613a..ef3ecc1f 100644 --- a/src/reader/async_tokio.rs +++ b/src/reader/async_tokio.rs @@ -9,9 +9,9 @@ use crate::events::Event; use crate::name::{QName, ResolveResult}; use crate::reader::buffered_reader::impl_buffered_source; use crate::reader::{ - is_whitespace, BangType, ElementParser, NsReader, ParseState, Parser, PiParser, ReadTextResult, - Reader, Span, + BangType, ElementParser, NsReader, ParseState, Parser, PiParser, ReadTextResult, Reader, Span, }; +use crate::utils::is_whitespace; /// A struct for read XML asynchronously from an [`AsyncBufRead`]. /// diff --git a/src/reader/buffered_reader.rs b/src/reader/buffered_reader.rs index a231956b..e395e4ae 100644 --- a/src/reader/buffered_reader.rs +++ b/src/reader/buffered_reader.rs @@ -8,7 +8,8 @@ use std::path::Path; use crate::errors::{Error, Result}; use crate::events::Event; use crate::name::QName; -use crate::reader::{is_whitespace, BangType, Parser, ReadTextResult, Reader, Span, XmlSource}; +use crate::reader::{BangType, Parser, ReadTextResult, Reader, Span, XmlSource}; +use crate::utils::is_whitespace; macro_rules! impl_buffered_source { ($($lf:lifetime, $reader:tt, $async:ident, $await:ident)?) => { diff --git a/src/reader/mod.rs b/src/reader/mod.rs index 4f353c00..15e5e4c6 100644 --- a/src/reader/mod.rs +++ b/src/reader/mod.rs @@ -865,6 +865,7 @@ trait XmlSource<'r, B> { /// /// A `P` type parameter is used to preserve state between calls to the underlying /// reader which provides bytes fed into the parser. + /// /// [events]: crate::events::Event fn read_with

(&mut self, parser: P, buf: B, position: &mut usize) -> Result<&'r [u8]> where @@ -991,22 +992,6 @@ impl BangType { } } -/// A function to check whether the byte is a whitespace (blank, new line, carriage return or tab) -#[inline] -pub(crate) const fn is_whitespace(b: u8) -> bool { - matches!(b, b' ' | b'\r' | b'\n' | b'\t') -} - -/// Calculates name from an element-like content. Name is the first word in `content`, -/// where word boundaries is XML space characters. -#[inline] -pub(crate) fn name_len(content: &[u8]) -> usize { - content - .iter() - .position(|&b| is_whitespace(b)) - .unwrap_or(content.len()) -} - //////////////////////////////////////////////////////////////////////////////////////////////////// #[cfg(test)] diff --git a/src/reader/slice_reader.rs b/src/reader/slice_reader.rs index 27155090..ed00f867 100644 --- a/src/reader/slice_reader.rs +++ b/src/reader/slice_reader.rs @@ -13,7 +13,8 @@ use encoding_rs::{Encoding, UTF_8}; use crate::errors::{Error, Result}; use crate::events::Event; use crate::name::QName; -use crate::reader::{is_whitespace, BangType, Parser, ReadTextResult, Reader, Span, XmlSource}; +use crate::reader::{BangType, Parser, ReadTextResult, Reader, Span, XmlSource}; +use crate::utils::is_whitespace; /// This is an implementation for reading from a `&[u8]` as underlying byte stream. /// This implementation supports not using an intermediate buffer as the byte slice diff --git a/src/reader/state.rs b/src/reader/state.rs index bf56d242..0099734e 100644 --- a/src/reader/state.rs +++ b/src/reader/state.rs @@ -6,7 +6,8 @@ use crate::errors::{Error, IllFormedError, Result, SyntaxError}; use crate::events::{BytesCData, BytesDecl, BytesEnd, BytesPI, BytesStart, BytesText, Event}; #[cfg(feature = "encoding")] use crate::reader::EncodingRef; -use crate::reader::{is_whitespace, name_len, BangType, Config, ParseState}; +use crate::reader::{BangType, Config, ParseState}; +use crate::utils::{is_whitespace, name_len}; /// A struct that holds a current reader state and a parser configuration. /// It is independent on a way of reading data: the reader feed data into it and diff --git a/src/utils.rs b/src/utils.rs index adf22899..09b6298b 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -197,6 +197,67 @@ impl<'de> Serialize for Bytes<'de> { //////////////////////////////////////////////////////////////////////////////////////////////////// +/// A function to check whether the byte is a whitespace (blank, new line, carriage return or tab). +#[inline] +pub const fn is_whitespace(b: u8) -> bool { + matches!(b, b' ' | b'\r' | b'\n' | b'\t') +} + +/// Calculates name from an element-like content. Name is the first word in `content`, +/// where word boundaries is XML whitespace characters. +/// +/// 'Whitespace' refers to the definition used by [`is_whitespace`]. +#[inline] +pub const fn name_len(mut bytes: &[u8]) -> usize { + // Note: A pattern matching based approach (instead of indexing) allows + // making the function const. + let mut len = 0; + while let [first, rest @ ..] = bytes { + if is_whitespace(*first) { + break; + } + len += 1; + bytes = rest; + } + len +} + +/// Returns a byte slice with leading XML whitespace bytes removed. +/// +/// 'Whitespace' refers to the definition used by [`is_whitespace`]. +#[inline] +pub const fn trim_xml_start(mut bytes: &[u8]) -> &[u8] { + // Note: A pattern matching based approach (instead of indexing) allows + // making the function const. + while let [first, rest @ ..] = bytes { + if is_whitespace(*first) { + bytes = rest; + } else { + break; + } + } + bytes +} + +/// Returns a byte slice with trailing XML whitespace bytes removed. +/// +/// 'Whitespace' refers to the definition used by [`is_whitespace`]. +#[inline] +pub const fn trim_xml_end(mut bytes: &[u8]) -> &[u8] { + // Note: A pattern matching based approach (instead of indexing) allows + // making the function const. + while let [rest @ .., last] = bytes { + if is_whitespace(*last) { + bytes = rest; + } else { + break; + } + } + bytes +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + #[cfg(test)] mod tests { use super::*; @@ -227,4 +288,39 @@ mod tests { ]); assert_eq!(format!("{:?}", bytes), r##""Class IRI=\"#B\"""##); } + + #[test] + fn name_len() { + assert_eq!(super::name_len(b""), 0); + assert_eq!(super::name_len(b" abc"), 0); + assert_eq!(super::name_len(b" \t\r\n"), 0); + + assert_eq!(super::name_len(b"abc"), 3); + assert_eq!(super::name_len(b"abc "), 3); + + assert_eq!(super::name_len(b"a bc"), 1); + assert_eq!(super::name_len(b"ab\tc"), 2); + assert_eq!(super::name_len(b"ab\rc"), 2); + assert_eq!(super::name_len(b"ab\nc"), 2); + } + + #[test] + fn trim_xml_start() { + assert_eq!(Bytes(super::trim_xml_start(b"")), Bytes(b"")); + assert_eq!(Bytes(super::trim_xml_start(b"abc")), Bytes(b"abc")); + assert_eq!( + Bytes(super::trim_xml_start(b"\r\n\t ab \t\r\nc \t\r\n")), + Bytes(b"ab \t\r\nc \t\r\n") + ); + } + + #[test] + fn trim_xml_end() { + assert_eq!(Bytes(super::trim_xml_end(b"")), Bytes(b"")); + assert_eq!(Bytes(super::trim_xml_end(b"abc")), Bytes(b"abc")); + assert_eq!( + Bytes(super::trim_xml_end(b"\r\n\t ab \t\r\nc \t\r\n")), + Bytes(b"\r\n\t ab \t\r\nc") + ); + } } From 4543ba6ccae14e8aaea20e86ea85831017f2dbed Mon Sep 17 00:00:00 2001 From: Mingun Date: Sun, 16 Jun 2024 00:44:08 +0500 Subject: [PATCH 2/2] Make `const` as many functions as possible - Attr::key() - Attr::value() - Attributes::html() - Attributes::new() - BytesDecl::from_start() - Decoder::encoding() - Deserializer::get_ref() - IoReader::get_ref() - LocalName::into_inner() - Namespace::into_inner() - NsReader::config() - NsReader::prefixes() - Prefix::into_inner() - QName::into_inner() - Reader::buffer_position() - Reader::config() - Reader::decoder() - Reader::error_position() - Reader::get_ref() - resolve_html5_entity() - resolve_predefined_entity() - resolve_xml_entity() - SliceReader::get_ref() - Writer::get_ref() - Writer::new() --- Changelog.md | 27 +++++++++++++++++++++++++++ src/de/mod.rs | 10 +++++----- src/de/simple_type.rs | 2 +- src/encoding.rs | 2 +- src/escape.rs | 6 +++--- src/events/attributes.rs | 12 ++++++------ src/events/mod.rs | 8 ++++---- src/name.rs | 10 +++++----- src/reader/mod.rs | 18 +++++++++--------- src/reader/ns_reader.rs | 4 ++-- src/reader/state.rs | 2 +- src/writer.rs | 4 ++-- 12 files changed, 66 insertions(+), 39 deletions(-) diff --git a/Changelog.md b/Changelog.md index 8cf9c2c2..603ceafb 100644 --- a/Changelog.md +++ b/Changelog.md @@ -22,10 +22,37 @@ ### Misc Changes - [#650]: Change the type of `Event::PI` to a new dedicated `BytesPI` type. +- [#759]: Make `const` as much functions as possible: + - `resolve_html5_entity()` + - `resolve_predefined_entity()` + - `resolve_xml_entity()` + - `Attr::key()` + - `Attr::value()` + - `Attributes::html()` + - `Attributes::new()` + - `BytesDecl::from_start()` + - `Decoder::encoding()` + - `Deserializer::get_ref()` + - `IoReader::get_ref()` + - `LocalName::into_inner()` + - `Namespace::into_inner()` + - `NsReader::config()` + - `NsReader::prefixes()` + - `Prefix::into_inner()` + - `QName::into_inner()` + - `Reader::buffer_position()` + - `Reader::config()` + - `Reader::decoder()` + - `Reader::error_position()` + - `Reader::get_ref()` + - `SliceReader::get_ref()` + - `Writer::get_ref()` + - `Writer::new()` [#650]: https://github.com/tafia/quick-xml/issues/650 [#755]: https://github.com/tafia/quick-xml/pull/755 [#758]: https://github.com/tafia/quick-xml/pull/758 +[#759]: https://github.com/tafia/quick-xml/pull/759 ## 0.32.0 -- 2024-06-10 diff --git a/src/de/mod.rs b/src/de/mod.rs index d274e2b6..1f1cd606 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -2155,7 +2155,7 @@ impl<'i, R: XmlRead<'i>, E: EntityResolver> XmlReader<'i, R, E> { } /// Returns `true` if all events was consumed - fn is_empty(&self) -> bool { + const fn is_empty(&self) -> bool { matches!(self.lookahead, Ok(PayloadEvent::Eof)) } @@ -2166,7 +2166,7 @@ impl<'i, R: XmlRead<'i>, E: EntityResolver> XmlReader<'i, R, E> { } #[inline(always)] - fn need_trim_end(&self) -> bool { + const fn need_trim_end(&self) -> bool { // If next event is a text or CDATA, we should not trim trailing spaces !matches!( self.lookahead, @@ -2464,7 +2464,7 @@ where /// assert_eq!(reader.error_position(), 28); /// assert_eq!(reader.buffer_position(), 41); /// ``` - pub fn get_ref(&self) -> &R { + pub const fn get_ref(&self) -> &R { &self.reader.reader } @@ -3127,7 +3127,7 @@ impl IoReader { /// assert_eq!(reader.error_position(), 28); /// assert_eq!(reader.buffer_position(), 41); /// ``` - pub fn get_ref(&self) -> &Reader { + pub const fn get_ref(&self) -> &Reader { &self.reader } } @@ -3194,7 +3194,7 @@ impl<'de> SliceReader<'de> { /// assert_eq!(reader.error_position(), 28); /// assert_eq!(reader.buffer_position(), 41); /// ``` - pub fn get_ref(&self) -> &Reader<&'de [u8]> { + pub const fn get_ref(&self) -> &Reader<&'de [u8]> { &self.reader } } diff --git a/src/de/simple_type.rs b/src/de/simple_type.rs index 517a2f76..5c102674 100644 --- a/src/de/simple_type.rs +++ b/src/de/simple_type.rs @@ -551,7 +551,7 @@ impl<'de, 'a> SimpleTypeDeserializer<'de, 'a> { /// Constructor for tests #[inline] - fn new(content: CowRef<'de, 'a, [u8]>, escaped: bool, decoder: Decoder) -> Self { + const fn new(content: CowRef<'de, 'a, [u8]>, escaped: bool, decoder: Decoder) -> Self { Self { content, escaped, diff --git a/src/encoding.rs b/src/encoding.rs index d7b0fe05..e18e2070 100644 --- a/src/encoding.rs +++ b/src/encoding.rs @@ -62,7 +62,7 @@ impl Decoder { /// /// [`decode`]: Self::decode #[cfg(feature = "encoding")] - pub fn encoding(&self) -> &'static Encoding { + pub const fn encoding(&self) -> &'static Encoding { self.encoding } diff --git a/src/escape.rs b/src/escape.rs index 54972624..ac6c9add 100644 --- a/src/escape.rs +++ b/src/escape.rs @@ -284,7 +284,7 @@ where /// Behaves like [`resolve_xml_entity`] if feature is not enabled and as /// [`resolve_html5_entity`] if enabled. #[inline] -pub fn resolve_predefined_entity(entity: &str) -> Option<&'static str> { +pub const fn resolve_predefined_entity(entity: &str) -> Option<&'static str> { #[cfg(not(feature = "escape-html"))] { resolve_xml_entity(entity) @@ -314,7 +314,7 @@ pub fn resolve_predefined_entity(entity: &str) -> Option<&'static str> { /// ``` /// /// [specification]: https://www.w3.org/TR/xml11/#sec-predefined-ent -pub fn resolve_xml_entity(entity: &str) -> Option<&'static str> { +pub const fn resolve_xml_entity(entity: &str) -> Option<&'static str> { // match over strings are not allowed in const functions let s = match entity.as_bytes() { b"lt" => "<", @@ -328,7 +328,7 @@ pub fn resolve_xml_entity(entity: &str) -> Option<&'static str> { } /// Resolves all HTML5 entities. For complete list see . -pub fn resolve_html5_entity(entity: &str) -> Option<&'static str> { +pub const fn resolve_html5_entity(entity: &str) -> Option<&'static str> { // imported from https://dev.w3.org/html5/html-author/charref // match over strings are not allowed in const functions //TODO: automate up-to-dating using https://html.spec.whatwg.org/entities.json diff --git a/src/events/attributes.rs b/src/events/attributes.rs index 3d5ca059..2d1abfde 100644 --- a/src/events/attributes.rs +++ b/src/events/attributes.rs @@ -195,7 +195,7 @@ pub struct Attributes<'a> { impl<'a> Attributes<'a> { /// Internal constructor, used by `BytesStart`. Supplies data in reader's encoding #[inline] - pub(crate) fn wrap(buf: &'a [u8], pos: usize, html: bool) -> Self { + pub(crate) const fn wrap(buf: &'a [u8], pos: usize, html: bool) -> Self { Self { bytes: buf, state: IterState::new(pos, html), @@ -203,12 +203,12 @@ impl<'a> Attributes<'a> { } /// Creates a new attribute iterator from a buffer. - pub fn new(buf: &'a str, pos: usize) -> Self { + pub const fn new(buf: &'a str, pos: usize) -> Self { Self::wrap(buf.as_bytes(), pos, false) } /// Creates a new attribute iterator from a buffer, allowing HTML attribute syntax. - pub fn html(buf: &'a str, pos: usize) -> Self { + pub const fn html(buf: &'a str, pos: usize) -> Self { Self::wrap(buf.as_bytes(), pos, true) } @@ -416,7 +416,7 @@ impl Attr { impl<'a> Attr<&'a [u8]> { /// Returns the key value #[inline] - pub fn key(&self) -> QName<'a> { + pub const fn key(&self) -> QName<'a> { QName(match self { Attr::DoubleQ(key, _) => key, Attr::SingleQ(key, _) => key, @@ -429,7 +429,7 @@ impl<'a> Attr<&'a [u8]> { /// /// [HTML specification]: https://www.w3.org/TR/2012/WD-html-markup-20120329/syntax.html#syntax-attr-empty #[inline] - pub fn value(&self) -> &'a [u8] { + pub const fn value(&self) -> &'a [u8] { match self { Attr::DoubleQ(_, value) => value, Attr::SingleQ(_, value) => value, @@ -518,7 +518,7 @@ pub(crate) struct IterState { } impl IterState { - pub fn new(offset: usize, html: bool) -> Self { + pub const fn new(offset: usize, html: bool) -> Self { Self { state: State::Next(offset), html, diff --git a/src/events/mod.rs b/src/events/mod.rs index a5009ba4..5dd22f45 100644 --- a/src/events/mod.rs +++ b/src/events/mod.rs @@ -77,7 +77,7 @@ pub struct BytesStart<'a> { impl<'a> BytesStart<'a> { /// Internal constructor, used by `Reader`. Supplies data in reader's encoding #[inline] - pub(crate) fn wrap(content: &'a [u8], name_len: usize) -> Self { + pub(crate) const fn wrap(content: &'a [u8], name_len: usize) -> Self { BytesStart { buf: Cow::Borrowed(content), name_len, @@ -405,7 +405,7 @@ impl<'a> BytesDecl<'a> { } /// Creates a `BytesDecl` from a `BytesStart` - pub fn from_start(start: BytesStart<'a>) -> Self { + pub const fn from_start(start: BytesStart<'a>) -> Self { Self { content: start } } @@ -620,7 +620,7 @@ pub struct BytesEnd<'a> { impl<'a> BytesEnd<'a> { /// Internal constructor, used by `Reader`. Supplies data in reader's encoding #[inline] - pub(crate) fn wrap(name: Cow<'a, [u8]>) -> Self { + pub(crate) const fn wrap(name: Cow<'a, [u8]>) -> Self { BytesEnd { name } } @@ -1018,7 +1018,7 @@ pub struct BytesPI<'a> { impl<'a> BytesPI<'a> { /// Creates a new `BytesPI` from a byte sequence in the specified encoding. #[inline] - pub(crate) fn wrap(content: &'a [u8], target_len: usize) -> Self { + pub(crate) const fn wrap(content: &'a [u8], target_len: usize) -> Self { Self { content: BytesStart::wrap(content, target_len), } diff --git a/src/name.rs b/src/name.rs index 6bb2e5c6..719436c1 100644 --- a/src/name.rs +++ b/src/name.rs @@ -20,7 +20,7 @@ pub struct QName<'a>(pub &'a [u8]); impl<'a> QName<'a> { /// Converts this name to an internal slice representation. #[inline(always)] - pub fn into_inner(self) -> &'a [u8] { + pub const fn into_inner(self) -> &'a [u8] { self.0 } @@ -137,7 +137,7 @@ pub struct LocalName<'a>(&'a [u8]); impl<'a> LocalName<'a> { /// Converts this name to an internal slice representation. #[inline(always)] - pub fn into_inner(self) -> &'a [u8] { + pub const fn into_inner(self) -> &'a [u8] { self.0 } } @@ -187,7 +187,7 @@ pub struct Prefix<'a>(&'a [u8]); impl<'a> Prefix<'a> { /// Extracts internal slice #[inline(always)] - pub fn into_inner(self) -> &'a [u8] { + pub const fn into_inner(self) -> &'a [u8] { self.0 } } @@ -252,7 +252,7 @@ impl<'a> Namespace<'a> { /// [non-normalized]: https://www.w3.org/TR/xml11/#AVNormalize /// [IRI reference]: https://datatracker.ietf.org/doc/html/rfc3987 #[inline(always)] - pub fn into_inner(self) -> &'a [u8] { + pub const fn into_inner(self) -> &'a [u8] { self.0 } //TODO: implement value normalization and use it when comparing namespaces @@ -618,7 +618,7 @@ impl NamespaceResolver { } #[inline] - pub fn iter(&self) -> PrefixIter { + pub const fn iter(&self) -> PrefixIter { PrefixIter { resolver: self, // We initialize the cursor to 2 to skip the two default namespaces xml: and xmlns: diff --git a/src/reader/mod.rs b/src/reader/mod.rs index 15e5e4c6..2511dcbe 100644 --- a/src/reader/mod.rs +++ b/src/reader/mod.rs @@ -495,7 +495,7 @@ enum EncodingRef { #[cfg(feature = "encoding")] impl EncodingRef { #[inline] - fn encoding(&self) -> &'static Encoding { + const fn encoding(&self) -> &'static Encoding { match self { Self::Implicit(e) => e, Self::Explicit(e) => e, @@ -504,7 +504,7 @@ impl EncodingRef { } } #[inline] - fn can_be_refined(&self) -> bool { + const fn can_be_refined(&self) -> bool { match self { Self::Implicit(_) | Self::BomDetected(_) => true, Self::Explicit(_) | Self::XmlDetected(_) => false, @@ -587,7 +587,7 @@ impl Reader { } /// Returns reference to the parser configuration - pub fn config(&self) -> &Config { + pub const fn config(&self) -> &Config { &self.state.config } @@ -657,7 +657,7 @@ impl Reader { } /// Gets a reference to the underlying reader. - pub fn get_ref(&self) -> &R { + pub const fn get_ref(&self) -> &R { &self.reader } @@ -667,7 +667,7 @@ impl Reader { } /// Gets the current byte position in the input data. - pub fn buffer_position(&self) -> usize { + pub const fn buffer_position(&self) -> usize { // when internal state is InsideMarkup, we have actually read until '<', // which we don't want to show if let ParseState::InsideMarkup = self.state.state { @@ -688,7 +688,7 @@ impl Reader { /// markup element (i. e. to the `<` character). /// /// This position is always `<= buffer_position()`. - pub fn error_position(&self) -> usize { + pub const fn error_position(&self) -> usize { self.state.last_error_offset } @@ -702,7 +702,7 @@ impl Reader { /// /// [`encoding`]: ../index.html#encoding #[inline] - pub fn decoder(&self) -> Decoder { + pub const fn decoder(&self) -> Decoder { self.state.decoder() } } @@ -912,7 +912,7 @@ enum BangType { } impl BangType { #[inline(always)] - fn new(byte: Option) -> Result { + const fn new(byte: Option) -> Result { Ok(match byte { Some(b'[') => Self::CData, Some(b'-') => Self::Comment, @@ -983,7 +983,7 @@ impl BangType { None } #[inline] - fn to_err(&self) -> Error { + const fn to_err(&self) -> Error { match self { Self::CData => Error::Syntax(SyntaxError::UnclosedCData), Self::Comment => Error::Syntax(SyntaxError::UnclosedComment), diff --git a/src/reader/ns_reader.rs b/src/reader/ns_reader.rs index 028f1364..cfeb73de 100644 --- a/src/reader/ns_reader.rs +++ b/src/reader/ns_reader.rs @@ -39,7 +39,7 @@ impl NsReader { /// Returns reference to the parser configuration #[inline] - pub fn config(&self) -> &Config { + pub const fn config(&self) -> &Config { self.reader.config() } @@ -129,7 +129,7 @@ impl NsReader { /// # quick_xml::Result::Ok(()) /// ``` #[inline] - pub fn prefixes(&self) -> PrefixIter { + pub const fn prefixes(&self) -> PrefixIter { self.ns_resolver.iter() } } diff --git a/src/reader/state.rs b/src/reader/state.rs index 0099734e..b2ab1065 100644 --- a/src/reader/state.rs +++ b/src/reader/state.rs @@ -292,7 +292,7 @@ impl ReaderState { /// defaults to UTF-8. /// /// [`encoding`]: ../../index.html#encoding - pub fn decoder(&self) -> Decoder { + pub const fn decoder(&self) -> Decoder { Decoder { #[cfg(feature = "encoding")] encoding: self.encoding.encoding(), diff --git a/src/writer.rs b/src/writer.rs index 0d1963a9..a1b6fa85 100644 --- a/src/writer.rs +++ b/src/writer.rs @@ -70,7 +70,7 @@ pub struct Writer { impl Writer { /// Creates a `Writer` from a generic writer. - pub fn new(inner: W) -> Writer { + pub const fn new(inner: W) -> Writer { Writer { writer: inner, indent: None, @@ -96,7 +96,7 @@ impl Writer { } /// Get a reference to the underlying writer. - pub fn get_ref(&self) -> &W { + pub const fn get_ref(&self) -> &W { &self.writer }