1 #![allow(missing_docs)]
2 use std
::path
::{Path, PathBuf}
;
4 use bstr
::{BStr, ByteSlice}
;
8 use crate::PathIdMapping
;
10 /// Various aggregate numbers collected from when the corresponding [`Cache`] was instantiated.
11 #[derive(Default, Clone, Copy, Debug)]
12 #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13 pub struct Statistics
{
14 /// The amount of platforms created to do further matching.
16 /// Information about the stack delegate.
17 pub delegate
: delegate
::Statistics
,
18 /// Information about attributes
19 pub attributes
: state
::attributes
::Statistics
,
20 /// Information about the ignore stack
21 pub ignore
: state
::ignore
::Statistics
,
26 /// Useful for checkout where directories need creation, but we need to access attributes as well.
27 CreateDirectoryAndAttributesStack
{
28 /// If there is a symlink or a file in our path, try to unlink it before creating the directory.
29 unlink_on_collision
: bool
,
30 /// State to handle attribute information
31 attributes
: state
::Attributes
,
33 /// Used when adding files, requiring access to both attributes and ignore information, for example during add operations.
34 AttributesAndIgnoreStack
{
35 /// State to handle attribute information
36 attributes
: state
::Attributes
,
37 /// State to handle exclusion information
38 ignore
: state
::Ignore
,
40 /// Used when providing worktree status information.
41 IgnoreStack(state
::Ignore
),
45 pub struct Platform
<'a
> {
52 /// Create a new instance with `worktree_root` being the base for all future paths we match.
53 /// `state` defines the capabilities of the cache.
54 /// The `case` configures attribute and exclusion case sensitivity at *query time*, which should match the case that
55 /// `state` might be configured with.
56 /// `buf` is used when reading files, and `id_mappings` should have been created with [`State::id_mappings_from_index()`].
58 worktree_root
: impl Into
<PathBuf
>,
60 case
: gix_glob
::pattern
::Case
,
62 id_mappings
: Vec
<PathIdMapping
>,
64 let root
= worktree_root
.into();
66 stack
: gix_fs
::Stack
::new(root
),
71 statistics
: Statistics
::default(),
76 /// Entry points for attribute query
78 /// Append the `relative` path to the root directory of the cache and efficiently create leading directories, while assuring that no
79 /// symlinks are in that path.
80 /// Unless `is_dir` is known with `Some(…)`, then `relative` points to a directory itself in which case the entire resulting
81 /// path is created as directory. If it's not known it is assumed to be a file.
82 /// `find` maybe used to lookup objects from an [id mapping][crate::cache::State::id_mappings_from_index()], with mappnigs
84 /// Provide access to cached information for that `relative` path via the returned platform.
85 pub fn at_path
<Find
, E
>(
87 relative
: impl AsRef
<Path
>,
90 ) -> std
::io
::Result
<Platform
<'_
>>
92 Find
: for<'a
> FnMut(&oid
, &'a
mut Vec
<u8>) -> Result
<gix_object
::BlobRef
<'a
>, E
>,
93 E
: std
::error
::Error
+ Send
+ Sync
+ '
static,
95 self.statistics
.platforms
+= 1;
96 let mut delegate
= StackDelegate
{
97 state
: &mut self.state
,
99 is_dir
: is_dir
.unwrap_or(false),
100 id_mappings
: &self.id_mappings
,
103 statistics
: &mut self.statistics
,
105 self.stack
.make_relative_path_current(relative
, &mut delegate
)?
;
106 Ok(Platform { parent: self, is_dir }
)
109 /// Obtain a platform for lookups from a repo-`relative` path, typically obtained from an index entry. `is_dir` should reflect
110 /// whether it's a directory or not, or left at `None` if unknown.
111 /// `find` maybe used to lookup objects from an [id mapping][crate::cache::State::id_mappings_from_index()].
112 /// All effects are similar to [`at_path()`][Self::at_path()].
114 /// If `relative` ends with `/` and `is_dir` is `None`, it is automatically assumed to be a directory.
118 /// on illformed UTF8 in `relative`
119 pub fn at_entry
<'r
, Find
, E
>(
121 relative
: impl Into
<&'r BStr
>,
122 is_dir
: Option
<bool
>,
124 ) -> std
::io
::Result
<Platform
<'_
>>
126 Find
: for<'a
> FnMut(&oid
, &'a
mut Vec
<u8>) -> Result
<gix_object
::BlobRef
<'a
>, E
>,
127 E
: std
::error
::Error
+ Send
+ Sync
+ '
static,
129 let relative
= relative
.into();
130 let relative_path
= gix_path
::from_bstr(relative
);
134 is_dir
.or_else(|| relative
.ends_with_str("/").then_some(true)),
142 /// Reset the statistics after returning them.
143 pub fn take_statistics(&mut self) -> Statistics
{
144 std
::mem
::take(&mut self.statistics
)
147 /// Return our state for applying changes.
148 pub fn state_mut(&mut self) -> &mut State
{
155 /// Return the statistics we gathered thus far.
156 pub fn statistics(&self) -> &Statistics
{
159 /// Return the state for introspection.
160 pub fn state(&self) -> &State
{
164 /// Return the base path against which all entries or paths should be relative to when querying.
166 /// Note that this path _may_ not be canonicalized.
167 pub fn base(&self) -> &Path
{
174 use delegate
::StackDelegate
;