use std::{borrow::Cow, convert::TryFrom};
use bstr::BStr;
use crate::{file::MetadataFilter, value, File};
impl<'event> File<'event> {
pub fn string(
&self,
section_name: impl AsRef<str>,
subsection_name: Option<&BStr>,
key: impl AsRef<str>,
) -> Option<Cow<'_, BStr>> {
self.string_filter(section_name, subsection_name, key, &mut |_| true)
}
pub fn string_by_key<'a>(&self, key: impl Into<&'a BStr>) -> Option<Cow<'_, BStr>> {
self.string_filter_by_key(key, &mut |_| true)
}
pub fn string_filter(
&self,
section_name: impl AsRef<str>,
subsection_name: Option<&BStr>,
key: impl AsRef<str>,
filter: &mut MetadataFilter,
) -> Option<Cow<'_, BStr>> {
self.raw_value_filter(section_name.as_ref(), subsection_name, key.as_ref(), filter)
.ok()
}
pub fn string_filter_by_key<'a>(
&self,
key: impl Into<&'a BStr>,
filter: &mut MetadataFilter,
) -> Option<Cow<'_, BStr>> {
let key = crate::parse::key(key.into())?;
self.raw_value_filter(key.section_name, key.subsection_name, key.value_name, filter)
.ok()
}
pub fn path(
&self,
section_name: impl AsRef<str>,
subsection_name: Option<&BStr>,
key: impl AsRef<str>,
) -> Option<crate::Path<'_>> {
self.path_filter(section_name, subsection_name, key, &mut |_| true)
}
pub fn path_by_key<'a>(&self, key: impl Into<&'a BStr>) -> Option<crate::Path<'_>> {
self.path_filter_by_key(key, &mut |_| true)
}
pub fn path_filter(
&self,
section_name: impl AsRef<str>,
subsection_name: Option<&BStr>,
key: impl AsRef<str>,
filter: &mut MetadataFilter,
) -> Option<crate::Path<'_>> {
self.raw_value_filter(section_name.as_ref(), subsection_name, key.as_ref(), filter)
.ok()
.map(crate::Path::from)
}
pub fn path_filter_by_key<'a>(
&self,
key: impl Into<&'a BStr>,
filter: &mut MetadataFilter,
) -> Option<crate::Path<'_>> {
let key = crate::parse::key(key.into())?;
self.path_filter(key.section_name, key.subsection_name, key.value_name, filter)
}
pub fn boolean(
&self,
section_name: impl AsRef<str>,
subsection_name: Option<&BStr>,
key: impl AsRef<str>,
) -> Option<Result<bool, value::Error>> {
self.boolean_filter(section_name, subsection_name, key, &mut |_| true)
}
pub fn boolean_by_key<'a>(&self, key: impl Into<&'a BStr>) -> Option<Result<bool, value::Error>> {
self.boolean_filter_by_key(key, &mut |_| true)
}
pub fn boolean_filter(
&self,
section_name: impl AsRef<str>,
subsection_name: Option<&BStr>,
key: impl AsRef<str>,
filter: &mut MetadataFilter,
) -> Option<Result<bool, value::Error>> {
let section_name = section_name.as_ref();
let section_ids = self
.section_ids_by_name_and_subname(section_name, subsection_name)
.ok()?;
let key = key.as_ref();
for section_id in section_ids.rev() {
let section = self.sections.get(§ion_id).expect("known section id");
if !filter(section.meta()) {
continue;
}
match section.value_implicit(key) {
Some(Some(v)) => return Some(crate::Boolean::try_from(v).map(Into::into)),
Some(None) => return Some(Ok(true)),
None => continue,
}
}
None
}
pub fn boolean_filter_by_key<'a>(
&self,
key: impl Into<&'a BStr>,
filter: &mut MetadataFilter,
) -> Option<Result<bool, value::Error>> {
let key = crate::parse::key(key.into())?;
self.boolean_filter(key.section_name, key.subsection_name, key.value_name, filter)
}
pub fn integer(
&self,
section_name: impl AsRef<str>,
subsection_name: Option<&BStr>,
key: impl AsRef<str>,
) -> Option<Result<i64, value::Error>> {
self.integer_filter(section_name, subsection_name, key, &mut |_| true)
}
pub fn integer_by_key<'a>(&self, key: impl Into<&'a BStr>) -> Option<Result<i64, value::Error>> {
self.integer_filter_by_key(key, &mut |_| true)
}
pub fn integer_filter(
&self,
section_name: impl AsRef<str>,
subsection_name: Option<&BStr>,
key: impl AsRef<str>,
filter: &mut MetadataFilter,
) -> Option<Result<i64, value::Error>> {
let int = self
.raw_value_filter(section_name.as_ref(), subsection_name, key.as_ref(), filter)
.ok()?;
Some(crate::Integer::try_from(int.as_ref()).and_then(|b| {
b.to_decimal()
.ok_or_else(|| value::Error::new("Integer overflow", int.into_owned()))
}))
}
pub fn integer_filter_by_key<'a>(
&self,
key: impl Into<&'a BStr>,
filter: &mut MetadataFilter,
) -> Option<Result<i64, value::Error>> {
let key = crate::parse::key(key.into())?;
self.integer_filter(key.section_name, key.subsection_name, key.value_name, filter)
}
pub fn strings(
&self,
section_name: impl AsRef<str>,
subsection_name: Option<&BStr>,
key: impl AsRef<str>,
) -> Option<Vec<Cow<'_, BStr>>> {
self.raw_values(section_name.as_ref(), subsection_name, key.as_ref())
.ok()
}
pub fn strings_by_key<'a>(&self, key: impl Into<&'a BStr>) -> Option<Vec<Cow<'_, BStr>>> {
let key = crate::parse::key(key.into())?;
self.strings(key.section_name, key.subsection_name, key.value_name)
}
pub fn strings_filter(
&self,
section_name: impl AsRef<str>,
subsection_name: Option<&BStr>,
key: impl AsRef<str>,
filter: &mut MetadataFilter,
) -> Option<Vec<Cow<'_, BStr>>> {
self.raw_values_filter(section_name.as_ref(), subsection_name, key.as_ref(), filter)
.ok()
}
pub fn strings_filter_by_key<'a>(
&self,
key: impl Into<&'a BStr>,
filter: &mut MetadataFilter,
) -> Option<Vec<Cow<'_, BStr>>> {
let key = crate::parse::key(key.into())?;
self.strings_filter(key.section_name, key.subsection_name, key.value_name, filter)
}
pub fn integers(
&self,
section_name: impl AsRef<str>,
subsection_name: Option<&BStr>,
key: impl AsRef<str>,
) -> Option<Result<Vec<i64>, value::Error>> {
self.integers_filter(section_name, subsection_name, key, &mut |_| true)
}
pub fn integers_by_key<'a>(&self, key: impl Into<&'a BStr>) -> Option<Result<Vec<i64>, value::Error>> {
self.integers_filter_by_key(key, &mut |_| true)
}
pub fn integers_filter(
&self,
section_name: impl AsRef<str>,
subsection_name: Option<&BStr>,
key: impl AsRef<str>,
filter: &mut MetadataFilter,
) -> Option<Result<Vec<i64>, value::Error>> {
self.raw_values_filter(section_name.as_ref(), subsection_name, key.as_ref(), filter)
.ok()
.map(|values| {
values
.into_iter()
.map(|v| {
crate::Integer::try_from(v.as_ref()).and_then(|int| {
int.to_decimal()
.ok_or_else(|| value::Error::new("Integer overflow", v.into_owned()))
})
})
.collect()
})
}
pub fn integers_filter_by_key<'a>(
&self,
key: impl Into<&'a BStr>,
filter: &mut MetadataFilter,
) -> Option<Result<Vec<i64>, value::Error>> {
let key = crate::parse::key(key.into())?;
self.integers_filter(key.section_name, key.subsection_name, key.value_name, filter)
}
}