summaryrefslogtreecommitdiffstats
path: root/vendor/gix-attributes/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:36 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:36 +0000
commite02c5b5930c2c9ba3e5423fe12e2ef0155017297 (patch)
treefd60ebbbb5299e16e5fca8c773ddb74f764760db /vendor/gix-attributes/src
parentAdding debian version 1.73.0+dfsg1-1. (diff)
downloadrustc-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.rs11
-rw-r--r--vendor/gix-attributes/src/name.rs10
-rw-r--r--vendor/gix-attributes/src/parse.rs5
-rw-r--r--vendor/gix-attributes/src/search/attributes.rs39
-rw-r--r--vendor/gix-attributes/src/search/mod.rs8
-rw-r--r--vendor/gix-attributes/src/search/outcome.rs75
-rw-r--r--vendor/gix-attributes/src/search/refmap.rs4
-rw-r--r--vendor/gix-attributes/src/state.rs41
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