diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:36 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 18:31:36 +0000 |
commit | e02c5b5930c2c9ba3e5423fe12e2ef0155017297 (patch) | |
tree | fd60ebbbb5299e16e5fca8c773ddb74f764760db /vendor/gix-attributes/src | |
parent | Adding debian version 1.73.0+dfsg1-1. (diff) | |
download | rustc-e02c5b5930c2c9ba3e5423fe12e2ef0155017297.tar.xz rustc-e02c5b5930c2c9ba3e5423fe12e2ef0155017297.zip |
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/gix-attributes/src')
-rw-r--r-- | vendor/gix-attributes/src/lib.rs | 11 | ||||
-rw-r--r-- | vendor/gix-attributes/src/name.rs | 10 | ||||
-rw-r--r-- | vendor/gix-attributes/src/parse.rs | 5 | ||||
-rw-r--r-- | vendor/gix-attributes/src/search/attributes.rs | 39 | ||||
-rw-r--r-- | vendor/gix-attributes/src/search/mod.rs | 8 | ||||
-rw-r--r-- | vendor/gix-attributes/src/search/outcome.rs | 75 | ||||
-rw-r--r-- | vendor/gix-attributes/src/search/refmap.rs | 4 | ||||
-rw-r--r-- | vendor/gix-attributes/src/state.rs | 41 |
8 files changed, 135 insertions, 58 deletions
diff --git a/vendor/gix-attributes/src/lib.rs b/vendor/gix-attributes/src/lib.rs index 7eaac4282..c45b8f9f3 100644 --- a/vendor/gix-attributes/src/lib.rs +++ b/vendor/gix-attributes/src/lib.rs @@ -8,8 +8,8 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![deny(missing_docs, rust_2018_idioms, unsafe_code)] +use byteyarn::{Yarn, YarnRef}; pub use gix_glob as glob; -use kstring::{KString, KStringRef}; mod assignment; /// @@ -34,7 +34,6 @@ pub fn parse(bytes: &[u8]) -> parse::Lines<'_> { /// /// Note that this doesn't contain the name. #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum StateRef<'a> { /// The attribute is listed, or has the special value 'true' Set, @@ -42,7 +41,6 @@ pub enum StateRef<'a> { Unset, /// The attribute is set to the given value, which followed the `=` sign. /// Note that values can be empty. - #[cfg_attr(feature = "serde", serde(borrow))] Value(state::ValueRef<'a>), /// The attribute isn't mentioned with a given path or is explicitly set to `Unspecified` using the `!` sign. Unspecified, @@ -52,7 +50,6 @@ pub enum StateRef<'a> { /// /// Note that this doesn't contain the name. #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum State { /// The attribute is listed, or has the special value 'true' Set, @@ -67,16 +64,14 @@ pub enum State { /// Represents a validated attribute name #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct Name(pub(crate) KString); +pub struct Name(pub(crate) Yarn); /// Holds a validated attribute name as a reference #[derive(Copy, Clone, PartialEq, Eq, Debug, Hash, Ord, PartialOrd)] -pub struct NameRef<'a>(KStringRef<'a>); +pub struct NameRef<'a>(YarnRef<'a, str>); /// Name an attribute and describe it's assigned state. #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Assignment { /// The validated name of the attribute. pub name: Name, diff --git a/vendor/gix-attributes/src/name.rs b/vendor/gix-attributes/src/name.rs index 40d86fd4c..43a78bddb 100644 --- a/vendor/gix-attributes/src/name.rs +++ b/vendor/gix-attributes/src/name.rs @@ -1,12 +1,16 @@ use bstr::{BStr, BString, ByteSlice}; -use kstring::KStringRef; +use byteyarn::YarnRef; use crate::{Name, NameRef}; impl<'a> NameRef<'a> { /// Turn this ref into its owned counterpart. pub fn to_owned(self) -> Name { - Name(self.0.into()) + Name( + self.0 + .immortalize() + .map_or_else(|| self.0.to_boxed_str().into(), YarnRef::to_box), + ) } /// Return the inner `str`. @@ -35,7 +39,7 @@ impl<'a> TryFrom<&'a BStr> for NameRef<'a> { } attr_valid(attr) - .then(|| NameRef(KStringRef::from_ref(attr.to_str().expect("no illformed utf8")))) + .then(|| NameRef(YarnRef::from(attr.to_str().expect("no illformed utf8")))) .ok_or_else(|| Error { attribute: attr.into() }) } } diff --git a/vendor/gix-attributes/src/parse.rs b/vendor/gix-attributes/src/parse.rs index 2d90a006d..7d8d6277a 100644 --- a/vendor/gix-attributes/src/parse.rs +++ b/vendor/gix-attributes/src/parse.rs @@ -1,13 +1,12 @@ use std::borrow::Cow; use bstr::{BStr, ByteSlice}; -use kstring::KStringRef; +use byteyarn::YarnRef; use crate::{name, AssignmentRef, Name, NameRef, StateRef}; /// The kind of attribute that was parsed. #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum Kind { /// A pattern to match paths against Pattern(gix_glob::Pattern), @@ -76,7 +75,7 @@ fn check_attr(attr: &BStr) -> Result<NameRef<'_>, name::Error> { } attr_valid(attr) - .then(|| NameRef(KStringRef::from_ref(attr.to_str().expect("no illformed utf8")))) + .then(|| NameRef(YarnRef::from(attr.to_str().expect("no illformed utf8")))) .ok_or_else(|| name::Error { attribute: attr.into() }) } diff --git a/vendor/gix-attributes/src/search/attributes.rs b/vendor/gix-attributes/src/search/attributes.rs index 078c187bb..88cc8356c 100644 --- a/vendor/gix-attributes/src/search/attributes.rs +++ b/vendor/gix-attributes/src/search/attributes.rs @@ -27,14 +27,14 @@ impl Search { let mut group = Self::default(); group.add_patterns_buffer( b"[attr]binary -diff -merge -text", - "[builtin]", + "[builtin]".into(), None, collection, true, /* allow macros */ ); for path in files.into_iter() { - group.add_patterns_file(path, true, None, buf, collection, true /* allow macros */)?; + group.add_patterns_file(path.into(), true, None, buf, collection, true /* allow macros */)?; } Ok(group) } @@ -49,7 +49,7 @@ impl Search { /// Returns `true` if the file was added, or `false` if it didn't exist. pub fn add_patterns_file( &mut self, - source: impl Into<PathBuf>, + source: PathBuf, follow_symlinks: bool, root: Option<&Path>, buf: &mut Vec<u8>, @@ -75,7 +75,7 @@ impl Search { pub fn add_patterns_buffer( &mut self, bytes: &[u8], - source: impl Into<PathBuf>, + source: PathBuf, root: Option<&Path>, collection: &mut MetadataCollection, allow_macros: bool, @@ -99,17 +99,17 @@ impl Search { impl Search { /// Match `relative_path`, a path relative to the repository, while respective `case`-sensitivity and write them to `out` /// Return `true` if at least one pattern matched. - pub fn pattern_matching_relative_path<'a, 'b>( - &'a self, - relative_path: impl Into<&'b BStr>, + pub fn pattern_matching_relative_path( + &self, + relative_path: &BStr, case: gix_glob::pattern::Case, + is_dir: Option<bool>, out: &mut Outcome, ) -> bool { - let relative_path = relative_path.into(); let basename_pos = relative_path.rfind(b"/").map(|p| p + 1); let mut has_match = false; self.patterns.iter().rev().any(|pl| { - has_match |= pattern_matching_relative_path(pl, relative_path, basename_pos, case, out); + has_match |= pattern_matching_relative_path(pl, relative_path, basename_pos, case, is_dir, out); out.is_done() }); has_match @@ -124,7 +124,7 @@ impl Search { impl Pattern for Attributes { type Value = Value; - fn bytes_to_patterns(bytes: &[u8], source: &std::path::Path) -> Vec<pattern::Mapping<Self::Value>> { + fn bytes_to_patterns(bytes: &[u8], _source: &std::path::Path) -> Vec<pattern::Mapping<Self::Value>> { fn into_owned_assignments<'a>( attrs: impl Iterator<Item = Result<crate::AssignmentRef<'a>, crate::name::Error>>, ) -> Option<Assignments> { @@ -138,8 +138,8 @@ impl Pattern for Attributes { .collect::<Result<Assignments, _>>(); match res { Ok(res) => Some(res), - Err(err) => { - log::warn!("{}", err); + Err(_err) => { + gix_trace::warn!("{}", _err); None } } @@ -148,8 +148,8 @@ impl Pattern for Attributes { crate::parse(bytes) .filter_map(|res| match res { Ok(pattern) => Some(pattern), - Err(err) => { - log::warn!("{}: {}", source.display(), err); + Err(_err) => { + gix_trace::warn!("{}: {}", _source.display(), _err); None } }) @@ -180,7 +180,9 @@ impl Pattern for Attributes { }) .collect() } +} +impl Attributes { fn may_use_glob_pattern(pattern: &gix_glob::Pattern) -> bool { pattern.mode != macro_mode() } @@ -201,6 +203,7 @@ fn pattern_matching_relative_path( relative_path: &BStr, basename_pos: Option<usize>, case: gix_glob::pattern::Case, + is_dir: Option<bool>, out: &mut Outcome, ) -> bool { let (relative_path, basename_start_pos) = @@ -227,7 +230,13 @@ fn pattern_matching_relative_path( Value::Assignments(attrs) => attrs, }; if out.has_unspecified_attributes(attrs.iter().map(|attr| attr.id)) - && pattern.matches_repo_relative_path(relative_path, basename_start_pos, None, case) + && pattern.matches_repo_relative_path( + relative_path, + basename_start_pos, + is_dir, + case, + gix_glob::wildmatch::Mode::NO_MATCH_SLASH_LITERAL, + ) { let all_filled = out.fill_attributes(attrs.iter(), pattern, list.source.as_ref(), *sequence_number); if all_filled { diff --git a/vendor/gix-attributes/src/search/mod.rs b/vendor/gix-attributes/src/search/mod.rs index e70c3b8b1..f06928bf2 100644 --- a/vendor/gix-attributes/src/search/mod.rs +++ b/vendor/gix-attributes/src/search/mod.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use kstring::KString; +use byteyarn::Yarn; use smallvec::SmallVec; use crate::{Assignment, AssignmentRef}; @@ -89,7 +89,7 @@ pub enum MatchKind { } /// The result of a search, containing all matching attributes. -#[derive(Default)] +#[derive(Default, Clone)] pub struct Outcome { /// The list of all available attributes, by ascending order. Each slots index corresponds to an attribute with that order, i.e. /// `arr[attr.id] = <attr info>`. @@ -99,7 +99,7 @@ pub struct Outcome { /// A stack of attributes to use for processing attributes of matched patterns and for resolving their macros. attrs_stack: SmallVec<[(AttributeId, Assignment, Option<AttributeId>); 8]>, /// A set of attributes we should limit ourselves to, or empty if we should fill in all attributes, made of - selected: SmallVec<[(KString, Option<AttributeId>); AVERAGE_NUM_ATTRS]>, + selected: SmallVec<[(Yarn, Option<AttributeId>); AVERAGE_NUM_ATTRS]>, /// storage for all patterns we have matched so far (in order to avoid referencing them, we copy them, but only once). patterns: RefMap<gix_glob::Pattern>, /// storage for all assignments we have matched so far (in order to avoid referencing them, we copy them, but only once). @@ -135,7 +135,7 @@ pub struct MetadataCollection { /// A mapping of an attribute or macro name to its order, that is the time when it was *first* seen. /// /// This is the inverse of the order attributes are searched. - name_to_meta: HashMap<KString, Metadata>, + name_to_meta: HashMap<Yarn, Metadata>, } /// Metadata associated with an attribute or macro name. diff --git a/vendor/gix-attributes/src/search/outcome.rs b/vendor/gix-attributes/src/search/outcome.rs index 469cae154..9ad8a81e1 100644 --- a/vendor/gix-attributes/src/search/outcome.rs +++ b/vendor/gix-attributes/src/search/outcome.rs @@ -1,6 +1,6 @@ use bstr::{BString, ByteSlice}; +use byteyarn::Yarn; use gix_glob::Pattern; -use kstring::{KString, KStringRef}; use crate::{ search::{ @@ -28,6 +28,10 @@ impl Outcome { }) { self.matches_by_id[order].macro_attributes = macro_attributes.clone() } + + for (name, id) in self.selected.iter_mut().filter(|(_, id)| id.is_none()) { + *id = collection.name_to_meta.get(name.as_str()).map(|meta| meta.id) + } } self.reset(); } @@ -40,16 +44,23 @@ impl Outcome { pub fn initialize_with_selection<'a>( &mut self, collection: &MetadataCollection, - attribute_names: impl IntoIterator<Item = impl Into<KStringRef<'a>>>, + attribute_names: impl IntoIterator<Item = impl Into<&'a str>>, + ) { + self.initialize_with_selection_inner(collection, &mut attribute_names.into_iter().map(Into::into)) + } + + fn initialize_with_selection_inner( + &mut self, + collection: &MetadataCollection, + attribute_names: &mut dyn Iterator<Item = &str>, ) { self.initialize(collection); self.selected.clear(); - self.selected.extend(attribute_names.into_iter().map(|name| { - let name = name.into(); + self.selected.extend(attribute_names.map(|name| { ( - name.to_owned(), - collection.name_to_meta.get(name.as_str()).map(|meta| meta.id), + Yarn::inlined(name).unwrap_or_else(|| name.to_string().into_boxed_str().into()), + collection.name_to_meta.get(name).map(|meta| meta.id), ) })); self.reset_remaining(); @@ -69,6 +80,26 @@ impl Outcome { self.selected.iter().filter(|(_name, id)| id.is_some()).count() }); } + + /// A performance optimization which allows results from this instance to be efficiently copied over to `dest`. + /// For this to work, `collection` must be the one used to initialize our state, and `dest` should not have been initialized + /// with any meaningful collection initially, i.e. be empty the first time this method is called. + /// + /// Note that it's safe to call it multiple times, so that it can be called after this instance was used to store a search result. + pub fn copy_into(&self, collection: &MetadataCollection, dest: &mut Self) { + dest.initialize(collection); + dest.matches_by_id = self.matches_by_id.clone(); + if dest.patterns.len() != self.patterns.len() { + dest.patterns = self.patterns.clone(); + } + if dest.assignments.len() != self.assignments.len() { + dest.assignments = self.assignments.clone(); + } + if dest.source_paths.len() != self.source_paths.len() { + dest.source_paths = self.source_paths.clone(); + } + dest.remaining = self.remaining; + } } /// Access @@ -219,6 +250,29 @@ impl Outcome { } } +impl std::fmt::Debug for Outcome { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + struct AsDisplay<'a>(&'a dyn std::fmt::Display); + impl std::fmt::Debug for AsDisplay<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } + } + + let mut dbg = f.debug_tuple("Outcome"); + if self.selected.is_empty() { + for match_ in self.iter() { + dbg.field(&AsDisplay(&match_.assignment)); + } + } else { + for match_ in self.iter_selected() { + dbg.field(&AsDisplay(&match_.assignment)); + } + } + dbg.finish() + } +} + /// Mutation impl MetadataCollection { /// Assign order ids to each attribute either in macros (along with macros themselves) or attributes of patterns, and store @@ -261,7 +315,7 @@ impl MetadataCollection { None => { let order = AttributeId(self.name_to_meta.len()); self.name_to_meta.insert( - KString::from_ref(name), + Yarn::inlined(name).unwrap_or_else(|| name.to_string().into_boxed_str().into()), Metadata { id: order, macro_attributes: Default::default(), @@ -281,7 +335,10 @@ impl MetadataCollection { Some(meta) => meta.id, None => { let order = AttributeId(self.name_to_meta.len()); - self.name_to_meta.insert(KString::from_ref(name), order.into()); + self.name_to_meta.insert( + Yarn::inlined(name).unwrap_or_else(|| name.to_string().into_boxed_str().into()), + order.into(), + ); order } } @@ -357,7 +414,7 @@ impl MatchLocation { crate::search::MatchLocation { source: self .source - .and_then(|source| out.source_paths.resolve(source).map(|p| p.as_path())), + .and_then(|source| out.source_paths.resolve(source).map(AsRef::as_ref)), sequence_number: self.sequence_number, } } diff --git a/vendor/gix-attributes/src/search/refmap.rs b/vendor/gix-attributes/src/search/refmap.rs index aa9dee84b..9a44b06da 100644 --- a/vendor/gix-attributes/src/search/refmap.rs +++ b/vendor/gix-attributes/src/search/refmap.rs @@ -8,6 +8,7 @@ use std::{ }; pub(crate) type RefMapKey = u64; +#[derive(Clone)] pub(crate) struct RefMap<T>(BTreeMap<RefMapKey, T>); impl<T> Default for RefMap<T> { @@ -20,6 +21,9 @@ impl<T> RefMap<T> where T: Hash + Clone, { + pub(crate) fn len(&self) -> usize { + self.0.len() + } pub(crate) fn insert(&mut self, value: &T) -> RefMapKey { let mut s = DefaultHasher::new(); value.hash(&mut s); diff --git a/vendor/gix-attributes/src/state.rs b/vendor/gix-attributes/src/state.rs index ffc0bce41..585e05adc 100644 --- a/vendor/gix-attributes/src/state.rs +++ b/vendor/gix-attributes/src/state.rs @@ -1,31 +1,26 @@ use bstr::{BStr, ByteSlice}; -use kstring::{KString, KStringRef}; +use byteyarn::{ByteYarn, YarnRef}; use crate::{State, StateRef}; /// A container to encapsulate a tightly packed and typically unallocated byte value that isn't necessarily UTF8 encoded. #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct Value(KString); +pub struct Value(ByteYarn); /// A reference container to encapsulate a tightly packed and typically unallocated byte value that isn't necessarily UTF8 encoded. #[derive(PartialEq, Eq, Debug, Hash, Ord, PartialOrd, Clone, Copy)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct ValueRef<'a>(#[cfg_attr(feature = "serde", serde(borrow))] KStringRef<'a>); +pub struct ValueRef<'a>(YarnRef<'a, [u8]>); -/// Conversions +/// Lifecycle impl<'a> ValueRef<'a> { /// Keep `input` as our value. pub fn from_bytes(input: &'a [u8]) -> Self { - Self(KStringRef::from_ref( - // SAFETY: our API makes accessing that value as `str` impossible, so illformed UTF8 is never exposed as such. - #[allow(unsafe_code)] - unsafe { - std::str::from_utf8_unchecked(input) - }, - )) + Self(YarnRef::from(input)) } +} +/// Access and conversions +impl ValueRef<'_> { /// Access this value as byte string. pub fn as_bstr(&self) -> &BStr { self.0.as_bytes().as_bstr() @@ -39,19 +34,25 @@ impl<'a> ValueRef<'a> { impl<'a> From<&'a str> for ValueRef<'a> { fn from(v: &'a str) -> Self { - ValueRef(v.into()) + ValueRef(v.as_bytes().into()) } } impl<'a> From<ValueRef<'a>> for Value { fn from(v: ValueRef<'a>) -> Self { - Value(v.0.into()) + Value( + v.0.immortalize() + .map_or_else(|| v.0.to_boxed_bytes().into(), YarnRef::to_box), + ) } } impl From<&str> for Value { fn from(v: &str) -> Self { - Value(KString::from_ref(v)) + Value( + ByteYarn::inlined(v.as_bytes()) + .unwrap_or_else(|| ByteYarn::from_boxed_bytes(v.as_bytes().to_vec().into_boxed_slice())), + ) } } @@ -79,6 +80,14 @@ impl StateRef<'_> { pub fn is_unset(&self) -> bool { matches!(self, StateRef::Unset) } + + /// Attempt to obtain the string value of this state, or return `None` if there is no such value. + pub fn as_bstr(&self) -> Option<&BStr> { + match self { + StateRef::Value(v) => Some(v.as_bstr()), + _ => None, + } + } } /// Initialization |