1 use std
::{borrow::Cow, convert::TryFrom}
;
5 use crate::{file::MetadataFilter, value, File}
;
7 /// Comfortable API for accessing values
8 impl<'event
> File
<'event
> {
9 /// Like [`value()`][File::value()], but returning `None` if the string wasn't found.
11 /// As strings perform no conversions, this will never fail.
14 section_name
: impl AsRef
<str>,
15 subsection_name
: Option
<&BStr
>,
17 ) -> Option
<Cow
<'_
, BStr
>> {
18 self.string_filter(section_name
, subsection_name
, key
, &mut |_
| true)
21 /// Like [`string()`][File::string()], but suitable for statically known `key`s like `remote.origin.url`.
22 pub fn string_by_key
<'a
>(&self, key
: impl Into
<&'a BStr
>) -> Option
<Cow
<'_
, BStr
>> {
23 self.string_filter_by_key(key
, &mut |_
| true)
26 /// Like [`string()`][File::string()], but the section containing the returned value must pass `filter` as well.
29 section_name
: impl AsRef
<str>,
30 subsection_name
: Option
<&BStr
>,
32 filter
: &mut MetadataFilter
,
33 ) -> Option
<Cow
<'_
, BStr
>> {
34 self.raw_value_filter(section_name
, subsection_name
, key
, filter
).ok()
37 /// Like [`string_filter()`][File::string_filter()], but suitable for statically known `key`s like `remote.origin.url`.
38 pub fn string_filter_by_key
<'a
>(
40 key
: impl Into
<&'a BStr
>,
41 filter
: &mut MetadataFilter
,
42 ) -> Option
<Cow
<'_
, BStr
>> {
43 let key
= crate::parse
::key(key
)?
;
44 self.raw_value_filter(key
.section_name
, key
.subsection_name
, key
.value_name
, filter
)
48 /// Like [`value()`][File::value()], but returning `None` if the path wasn't found.
50 /// Note that this path is not vetted and should only point to resources which can't be used
51 /// to pose a security risk. Prefer using [`path_filter()`][File::path_filter()] instead.
53 /// As paths perform no conversions, this will never fail.
56 section_name
: impl AsRef
<str>,
57 subsection_name
: Option
<&BStr
>,
59 ) -> Option
<crate::Path
<'_
>> {
60 self.path_filter(section_name
, subsection_name
, key
, &mut |_
| true)
63 /// Like [`path()`][File::path()], but suitable for statically known `key`s like `remote.origin.url`.
64 pub fn path_by_key
<'a
>(&self, key
: impl Into
<&'a BStr
>) -> Option
<crate::Path
<'_
>> {
65 self.path_filter_by_key(key
, &mut |_
| true)
68 /// Like [`path()`][File::path()], but the section containing the returned value must pass `filter` as well.
70 /// This should be the preferred way of accessing paths as those from untrusted
73 /// As paths perform no conversions, this will never fail.
76 section_name
: impl AsRef
<str>,
77 subsection_name
: Option
<&BStr
>,
79 filter
: &mut MetadataFilter
,
80 ) -> Option
<crate::Path
<'_
>> {
81 self.raw_value_filter(section_name
, subsection_name
, key
, filter
)
83 .map(crate::Path
::from
)
86 /// Like [`path_filter()`][File::path_filter()], but suitable for statically known `key`s like `remote.origin.url`.
87 pub fn path_filter_by_key
<'a
>(
89 key
: impl Into
<&'a BStr
>,
90 filter
: &mut MetadataFilter
,
91 ) -> Option
<crate::Path
<'_
>> {
92 let key
= crate::parse
::key(key
)?
;
93 self.path_filter(key
.section_name
, key
.subsection_name
, key
.value_name
, filter
)
96 /// Like [`value()`][File::value()], but returning `None` if the boolean value wasn't found.
99 section_name
: impl AsRef
<str>,
100 subsection_name
: Option
<&BStr
>,
101 key
: impl AsRef
<str>,
102 ) -> Option
<Result
<bool
, value
::Error
>> {
103 self.boolean_filter(section_name
, subsection_name
, key
, &mut |_
| true)
106 /// Like [`boolean()`][File::boolean()], but suitable for statically known `key`s like `remote.origin.url`.
107 pub fn boolean_by_key
<'a
>(&self, key
: impl Into
<&'a BStr
>) -> Option
<Result
<bool
, value
::Error
>> {
108 self.boolean_filter_by_key(key
, &mut |_
| true)
111 /// Like [`boolean()`][File::boolean()], but the section containing the returned value must pass `filter` as well.
112 pub fn boolean_filter(
114 section_name
: impl AsRef
<str>,
115 subsection_name
: Option
<&BStr
>,
116 key
: impl AsRef
<str>,
117 filter
: &mut MetadataFilter
,
118 ) -> Option
<Result
<bool
, value
::Error
>> {
119 let section_name
= section_name
.as_ref();
120 let section_ids
= self
121 .section_ids_by_name_and_subname(section_name
, subsection_name
)
123 let key
= key
.as_ref();
124 for section_id
in section_ids
.rev() {
125 let section
= self.sections
.get(§ion_id
).expect("known section id");
126 if !filter(section
.meta()) {
129 match section
.value_implicit(key
) {
130 Some(Some(v
)) => return Some(crate::Boolean
::try_from(v
).map(|b
| b
.into())),
131 Some(None
) => return Some(Ok(true)),
138 /// Like [`boolean_filter()`][File::boolean_filter()], but suitable for statically known `key`s like `remote.origin.url`.
139 pub fn boolean_filter_by_key
<'a
>(
141 key
: impl Into
<&'a BStr
>,
142 filter
: &mut MetadataFilter
,
143 ) -> Option
<Result
<bool
, value
::Error
>> {
144 let key
= crate::parse
::key(key
)?
;
145 self.boolean_filter(key
.section_name
, key
.subsection_name
, key
.value_name
, filter
)
148 /// Like [`value()`][File::value()], but returning an `Option` if the integer wasn't found.
151 section_name
: impl AsRef
<str>,
152 subsection_name
: Option
<&BStr
>,
153 key
: impl AsRef
<str>,
154 ) -> Option
<Result
<i64, value
::Error
>> {
155 self.integer_filter(section_name
, subsection_name
, key
, &mut |_
| true)
158 /// Like [`integer()`][File::integer()], but suitable for statically known `key`s like `remote.origin.url`.
159 pub fn integer_by_key
<'a
>(&self, key
: impl Into
<&'a BStr
>) -> Option
<Result
<i64, value
::Error
>> {
160 self.integer_filter_by_key(key
, &mut |_
| true)
163 /// Like [`integer()`][File::integer()], but the section containing the returned value must pass `filter` as well.
164 pub fn integer_filter(
166 section_name
: impl AsRef
<str>,
167 subsection_name
: Option
<&BStr
>,
168 key
: impl AsRef
<str>,
169 filter
: &mut MetadataFilter
,
170 ) -> Option
<Result
<i64, value
::Error
>> {
171 let int
= self.raw_value_filter(section_name
, subsection_name
, key
, filter
).ok()?
;
172 Some(crate::Integer
::try_from(int
.as_ref()).and_then(|b
| {
174 .ok_or_else(|| value
::Error
::new("Integer overflow", int
.into_owned()))
178 /// Like [`integer_filter()`][File::integer_filter()], but suitable for statically known `key`s like `remote.origin.url`.
179 pub fn integer_filter_by_key
<'a
>(
181 key
: impl Into
<&'a BStr
>,
182 filter
: &mut MetadataFilter
,
183 ) -> Option
<Result
<i64, value
::Error
>> {
184 let key
= crate::parse
::key(key
)?
;
185 self.integer_filter(key
.section_name
, key
.subsection_name
, key
.value_name
, filter
)
188 /// Similar to [`values(…)`][File::values()] but returning strings if at least one of them was found.
191 section_name
: impl AsRef
<str>,
192 subsection_name
: Option
<&BStr
>,
193 key
: impl AsRef
<str>,
194 ) -> Option
<Vec
<Cow
<'_
, BStr
>>> {
195 self.raw_values(section_name
, subsection_name
, key
).ok()
198 /// Like [`strings()`][File::strings()], but suitable for statically known `key`s like `remote.origin.url`.
199 pub fn strings_by_key
<'a
>(&self, key
: impl Into
<&'a BStr
>) -> Option
<Vec
<Cow
<'_
, BStr
>>> {
200 let key
= crate::parse
::key(key
)?
;
201 self.strings(key
.section_name
, key
.subsection_name
, key
.value_name
)
204 /// Similar to [`strings(…)`][File::strings()], but all values are in sections that passed `filter`.
205 pub fn strings_filter(
207 section_name
: impl AsRef
<str>,
208 subsection_name
: Option
<&BStr
>,
209 key
: impl AsRef
<str>,
210 filter
: &mut MetadataFilter
,
211 ) -> Option
<Vec
<Cow
<'_
, BStr
>>> {
212 self.raw_values_filter(section_name
, subsection_name
, key
, filter
).ok()
215 /// Like [`strings_filter()`][File::strings_filter()], but suitable for statically known `key`s like `remote.origin.url`.
216 pub fn strings_filter_by_key
<'a
>(
218 key
: impl Into
<&'a BStr
>,
219 filter
: &mut MetadataFilter
,
220 ) -> Option
<Vec
<Cow
<'_
, BStr
>>> {
221 let key
= crate::parse
::key(key
)?
;
222 self.strings_filter(key
.section_name
, key
.subsection_name
, key
.value_name
, filter
)
225 /// Similar to [`values(…)`][File::values()] but returning integers if at least one of them was found
226 /// and if none of them overflows.
229 section_name
: impl AsRef
<str>,
230 subsection_name
: Option
<&BStr
>,
231 key
: impl AsRef
<str>,
232 ) -> Option
<Result
<Vec
<i64>, value
::Error
>> {
233 self.integers_filter(section_name
, subsection_name
, key
, &mut |_
| true)
236 /// Like [`integers()`][File::integers()], but suitable for statically known `key`s like `remote.origin.url`.
237 pub fn integers_by_key
<'a
>(&self, key
: impl Into
<&'a BStr
>) -> Option
<Result
<Vec
<i64>, value
::Error
>> {
238 self.integers_filter_by_key(key
, &mut |_
| true)
241 /// Similar to [`integers(…)`][File::integers()] but all integers are in sections that passed `filter`
242 /// and that are not overflowing.
243 pub fn integers_filter(
245 section_name
: impl AsRef
<str>,
246 subsection_name
: Option
<&BStr
>,
247 key
: impl AsRef
<str>,
248 filter
: &mut MetadataFilter
,
249 ) -> Option
<Result
<Vec
<i64>, value
::Error
>> {
250 self.raw_values_filter(section_name
, subsection_name
, key
, filter
)
256 crate::Integer
::try_from(v
.as_ref()).and_then(|int
| {
258 .ok_or_else(|| value
::Error
::new("Integer overflow", v
.into_owned()))
265 /// Like [`integers_filter()`][File::integers_filter()], but suitable for statically known `key`s like `remote.origin.url`.
266 pub fn integers_filter_by_key
<'a
>(
268 key
: impl Into
<&'a BStr
>,
269 filter
: &mut MetadataFilter
,
270 ) -> Option
<Result
<Vec
<i64>, value
::Error
>> {
271 let key
= crate::parse
::key(key
)?
;
272 self.integers_filter(key
.section_name
, key
.subsection_name
, key
.value_name
, filter
)