use journal_index::FieldName;
use std::hash::Hash;
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct Facets {
fields: Arc<Vec<FieldName>>,
precomputed_hash: u64,
}
impl Hash for Facets {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
state.write_u64(self.precomputed_hash);
}
}
impl PartialEq for Facets {
fn eq(&self, other: &Self) -> bool {
if self.precomputed_hash != other.precomputed_hash {
return false;
}
Arc::ptr_eq(&self.fields, &other.fields) || self.fields == other.fields
}
}
impl Eq for Facets {}
impl Facets {
fn default_facets() -> Vec<FieldName> {
let v: Vec<&str> = vec![
"_HOSTNAME",
"PRIORITY",
"SYSLOG_FACILITY",
"ERRNO",
"SYSLOG_IDENTIFIER",
"USER_UNIT",
"MESSAGE_ID",
"_BOOT_ID",
"_SYSTEMD_OWNER_UID",
"_UID",
"OBJECT_SYSTEMD_OWNER_UID",
"OBJECT_UID",
"_GID",
"OBJECT_GID",
"_CAP_EFFECTIVE",
"_AUDIT_LOGINUID",
"OBJECT_AUDIT_LOGINUID",
"CODE_FUNC",
"CODE_FILE",
"_SELINUX_CONTEXT",
"_MACHINE_ID",
"_SYSTEMD_SLICE",
"_EXE",
"_NAMESPACE",
"_TRANSPORT",
"_RUNTIME_SCOPE",
"_STREAM_ID",
"_COMM",
"_SYSTEMD_USER_UNIT",
"_SYSTEMD_USER_SLICE",
];
v.into_iter().map(FieldName::new_unchecked).collect()
}
pub fn new(facets: &[String]) -> Self {
let mut facets = if facets.is_empty() {
Self::default_facets()
} else {
facets
.iter()
.filter_map(|s| FieldName::new(s.clone()))
.collect()
};
facets.sort();
facets.dedup();
use std::hash::Hasher;
let mut hasher = std::hash::DefaultHasher::new();
for field in &facets {
field.as_str().hash(&mut hasher);
}
let precomputed_hash = hasher.finish();
Self {
fields: Arc::new(facets),
precomputed_hash,
}
}
pub fn iter(&self) -> impl Iterator<Item = &FieldName> {
self.fields.iter()
}
pub fn as_slice(&self) -> &[FieldName] {
&self.fields
}
pub fn len(&self) -> usize {
self.fields.len()
}
#[allow(dead_code)]
pub fn is_empty(&self) -> bool {
self.fields.is_empty()
}
pub fn precomputed_hash(&self) -> u64 {
self.precomputed_hash
}
}
impl serde::Serialize for Facets {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
use serde::ser::SerializeSeq;
let mut seq = serializer.serialize_seq(Some(self.fields.len()))?;
for field in self.fields.iter() {
seq.serialize_element(field.as_str())?;
}
seq.end()
}
}
impl<'de> serde::Deserialize<'de> for Facets {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let fields: Vec<String> = Vec::deserialize(deserializer)?;
Ok(Facets::new(&fields))
}
}