use std::fmt;
use std::str::FromStr;
use serde::ser::SerializeSeq;
use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
use smallvec::SmallVec;
use crate::traits::IntoValue;
use crate::value::{Map, Value};
pub type Range = (usize, usize);
#[derive(Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum RemarkType {
#[serde(rename = "a")]
Annotated,
#[serde(rename = "x")]
Removed,
#[serde(rename = "s")]
Substituted,
#[serde(rename = "m")]
Masked,
#[serde(rename = "p")]
Pseudonymized,
#[serde(rename = "e")]
Encrypted,
}
#[derive(Clone, Debug, PartialEq)]
pub struct Remark {
pub ty: RemarkType,
pub rule_id: String,
pub range: Option<Range>,
}
impl Remark {
pub fn new<S: Into<String>>(ty: RemarkType, rule_id: S) -> Self {
Remark {
rule_id: rule_id.into(),
ty,
range: None,
}
}
pub fn with_range<S: Into<String>>(ty: RemarkType, rule_id: S, range: Range) -> Self {
Remark {
rule_id: rule_id.into(),
ty,
range: Some(range),
}
}
pub fn rule_id(&self) -> &str {
&self.rule_id
}
pub fn range(&self) -> Option<&Range> {
self.range.as_ref()
}
pub fn len(&self) -> Option<usize> {
self.range.map(|r| r.1 - r.0)
}
pub fn is_empty(&self) -> bool {
self.len().map_or(false, |l| l == 0)
}
pub fn ty(&self) -> RemarkType {
self.ty
}
}
impl<'de> Deserialize<'de> for Remark {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
struct RemarkVisitor;
impl<'de> de::Visitor<'de> for RemarkVisitor {
type Value = Remark;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "a meta remark")
}
fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let rule_id = seq
.next_element()?
.ok_or_else(|| de::Error::custom("missing required rule-id"))?;
let ty = seq
.next_element()?
.ok_or_else(|| de::Error::custom("missing required remark-type"))?;
let start = seq.next_element()?;
let end = seq.next_element()?;
while let Some(de::IgnoredAny) = seq.next_element()? {}
let range = match (start, end) {
(Some(start), Some(end)) => Some((start, end)),
_ => None,
};
Ok(Remark { ty, rule_id, range })
}
}
deserializer.deserialize_seq(RemarkVisitor)
}
}
impl Serialize for Remark {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut seq = serializer.serialize_seq(None)?;
seq.serialize_element(self.rule_id())?;
seq.serialize_element(&self.ty())?;
if let Some(range) = self.range() {
seq.serialize_element(&range.0)?;
seq.serialize_element(&range.1)?;
}
seq.end()
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum ErrorKind {
InvalidData,
MissingAttribute,
InvalidAttribute,
ValueTooLong,
ClockDrift,
PastTimestamp,
FutureTimestamp,
Unknown(String),
}
impl ErrorKind {
fn parse<S>(string: S) -> Self
where
S: AsRef<str> + Into<String>,
{
match string.as_ref() {
"invalid_data" => ErrorKind::InvalidData,
"missing_attribute" => ErrorKind::MissingAttribute,
"invalid_attribute" => ErrorKind::InvalidAttribute,
"value_too_long" => ErrorKind::ValueTooLong,
"past_timestamp" => ErrorKind::PastTimestamp,
"future_timestamp" => ErrorKind::FutureTimestamp,
_ => ErrorKind::Unknown(string.into()),
}
}
pub fn as_str(&self) -> &str {
match self {
ErrorKind::InvalidData => "invalid_data",
ErrorKind::MissingAttribute => "missing_attribute",
ErrorKind::InvalidAttribute => "invalid_attribute",
ErrorKind::ValueTooLong => "value_too_long",
ErrorKind::PastTimestamp => "past_timestamp",
ErrorKind::FutureTimestamp => "future_timestamp",
ErrorKind::ClockDrift => "clock_drift",
ErrorKind::Unknown(error) => error,
}
}
}
impl fmt::Display for ErrorKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.as_str())
}
}
impl From<String> for ErrorKind {
fn from(string: String) -> Self {
ErrorKind::parse(string)
}
}
impl<'a> From<&'a str> for ErrorKind {
fn from(string: &'a str) -> Self {
ErrorKind::parse(string)
}
}
impl FromStr for ErrorKind {
type Err = ();
fn from_str(string: &str) -> Result<Self, Self::Err> {
Ok(ErrorKind::from(string))
}
}
impl<'de> Deserialize<'de> for ErrorKind {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
struct ErrorKindVisitor;
impl de::Visitor<'_> for ErrorKindVisitor {
type Value = ErrorKind;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "an error kind")
}
fn visit_str<E>(self, string: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(ErrorKind::from(string))
}
fn visit_string<E>(self, string: String) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(ErrorKind::from(string))
}
}
deserializer.deserialize_str(ErrorKindVisitor)
}
}
impl Serialize for ErrorKind {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.as_str())
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct Error {
kind: ErrorKind,
data: Map<String, Value>,
}
impl Error {
#[inline]
fn with_data(kind: ErrorKind, data: Map<String, Value>) -> Self {
Error { kind, data }
}
#[inline]
pub fn new(kind: ErrorKind) -> Self {
Error::with_data(kind, Map::default())
}
#[inline]
pub fn with<F>(kind: ErrorKind, f: F) -> Self
where
F: FnOnce(&mut Self),
{
let mut error = Error::new(kind);
f(&mut error);
error
}
pub fn invalid<S>(reason: S) -> Self
where
S: std::fmt::Display,
{
Error::with(ErrorKind::InvalidData, |error| {
error.insert("reason", reason.to_string());
})
}
pub fn expected(expectation: &str) -> Self {
Error::with(ErrorKind::InvalidData, |error| {
error.insert("reason", format!("expected {expectation}"));
})
}
pub fn nonempty() -> Self {
Error::invalid("expected a non-empty value")
}
pub fn nonempty_string() -> Self {
Error::invalid("expected a non-empty string")
}
pub fn kind(&self) -> &ErrorKind {
&self.kind
}
pub fn data(&self) -> impl Iterator<Item = (&str, &Value)> {
self.data.iter().map(|(k, v)| (k.as_str(), v))
}
pub fn insert<K, V>(&mut self, key: K, value: V) -> Option<Value>
where
K: Into<String>,
V: Into<Value>,
{
self.data.insert(key.into(), value.into())
}
pub fn get<K>(&self, key: K) -> Option<&Value>
where
K: AsRef<str>,
{
self.data.get(key.as_ref())
}
}
impl From<ErrorKind> for Error {
fn from(kind: ErrorKind) -> Self {
Error::new(kind)
}
}
impl<'de> Deserialize<'de> for Error {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
struct ErrorVisitor;
impl<'de> de::Visitor<'de> for ErrorVisitor {
type Value = Error;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(formatter, "a meta remark")
}
fn visit_str<E>(self, string: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Error::new(ErrorKind::from(string)))
}
fn visit_string<E>(self, string: String) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(Error::new(ErrorKind::from(string)))
}
fn visit_seq<A: de::SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
let kind = seq
.next_element()?
.ok_or_else(|| de::Error::custom("missing error kind"))?;
let data = seq.next_element()?.unwrap_or_default();
while let Some(de::IgnoredAny) = seq.next_element()? {}
Ok(Error::with_data(kind, data))
}
}
deserializer.deserialize_any(ErrorVisitor)
}
}
impl Serialize for Error {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
if self.data.is_empty() {
return self.kind.serialize(serializer);
}
let mut seq = serializer.serialize_seq(None)?;
seq.serialize_element(&self.kind)?;
seq.serialize_element(&self.data)?;
seq.end()
}
}
#[derive(Clone, Deserialize, Serialize)]
struct MetaInner {
#[serde(default, skip_serializing_if = "SmallVec::is_empty", rename = "rem")]
remarks: SmallVec<[Remark; 3]>,
#[serde(default, skip_serializing_if = "SmallVec::is_empty", rename = "err")]
errors: SmallVec<[Error; 3]>,
#[serde(default, skip_serializing_if = "Option::is_none", rename = "len")]
original_length: Option<u32>,
#[serde(default, skip_serializing_if = "Option::is_none", rename = "val")]
original_value: Option<Value>,
}
impl MetaInner {
pub fn is_empty(&self) -> bool {
self.original_length.is_none()
&& self.remarks.is_empty()
&& self.errors.is_empty()
&& self.original_value.is_none()
}
}
#[derive(Clone, Default, Serialize)]
pub struct Meta(Option<Box<MetaInner>>);
impl fmt::Debug for Meta {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Meta")
.field("remarks", &self.remarks())
.field("errors", &self.errors())
.field("original_length", &self.original_length())
.field("original_value", &self.original_value())
.finish()
}
}
impl<'de> Deserialize<'de> for Meta {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Meta, D::Error>
where
D: serde::Deserializer<'de>,
{
Ok(match <Option<MetaInner>>::deserialize(deserializer)? {
Some(value) => {
if value.is_empty() {
Meta(None)
} else {
Meta(Some(Box::new(value)))
}
}
None => Meta(None),
})
}
}
impl Meta {
pub fn from_error<E: Into<Error>>(err: E) -> Self {
let mut meta = Self::default();
meta.add_error(err);
meta
}
fn upsert(&mut self) -> &mut MetaInner {
self.0.get_or_insert_with(Box::default)
}
pub fn original_length(&self) -> Option<usize> {
self.0
.as_ref()
.and_then(|x| x.original_length.map(|x| x as usize))
}
pub fn set_original_length(&mut self, original_length: Option<usize>) {
let inner = self.upsert();
if inner.original_length.is_none() {
inner.original_length = original_length.map(|x| x as u32);
}
}
fn remarks(&self) -> &[Remark] {
match self.0 {
Some(ref inner) => &inner.remarks[..],
None => &[][..],
}
}
pub fn iter_remarks(&self) -> impl Iterator<Item = &Remark> {
self.remarks().iter()
}
pub fn clear_remarks(&mut self) {
if let Some(ref mut inner) = self.0 {
inner.remarks.clear();
}
}
pub fn add_remark(&mut self, remark: Remark) {
self.upsert().remarks.push(remark);
}
fn errors(&self) -> &[Error] {
match self.0 {
Some(ref inner) => &inner.errors[..],
None => &[][..],
}
}
pub fn iter_errors(&self) -> impl Iterator<Item = &Error> {
self.errors().iter()
}
pub fn add_error<E: Into<Error>>(&mut self, err: E) {
let errors = &mut self.upsert().errors;
let err = err.into();
if errors.contains(&err) {
return;
}
errors.push(err);
}
pub fn original_value(&self) -> Option<&Value> {
self.0.as_ref().and_then(|x| x.original_value.as_ref())
}
pub fn original_value_as_mut(&mut self) -> Option<&mut Value> {
self.0.as_mut().and_then(|x| x.original_value.as_mut())
}
pub fn set_original_value<T>(&mut self, original_value: Option<T>)
where
T: IntoValue,
{
if crate::size::estimate_size(original_value.as_ref()) < 500 {
self.upsert().original_value = original_value.map(IntoValue::into_value);
}
}
pub fn take_original_value(&mut self) -> Option<Value> {
self.0.as_mut().and_then(|x| x.original_value.take())
}
pub fn has_errors(&self) -> bool {
self.0.as_ref().map_or(false, |x| !x.errors.is_empty())
}
pub fn is_empty(&self) -> bool {
self.0.as_ref().map_or(true, |x| x.is_empty())
}
pub fn merge(mut self, other: Self) -> Self {
if let Some(other_inner) = other.0 {
let other_inner = *other_inner;
let inner = self.upsert();
inner.remarks.extend(other_inner.remarks);
inner.errors.extend(other_inner.errors);
if inner.original_length.is_none() {
inner.original_length = other_inner.original_length;
}
if inner.original_value.is_none() {
inner.original_value = other_inner.original_value;
}
}
self
}
}
impl Default for MetaInner {
fn default() -> Self {
MetaInner {
remarks: SmallVec::new(),
errors: SmallVec::new(),
original_length: None,
original_value: None,
}
}
}
impl PartialEq for MetaInner {
fn eq(&self, other: &Self) -> bool {
self.remarks == other.remarks
&& self.errors == other.errors
&& self.original_length == other.original_length
&& self.original_value == other.original_value
}
}
impl PartialEq for Meta {
fn eq(&self, other: &Self) -> bool {
if self.is_empty() && other.is_empty() {
true
} else {
match (self.0.as_ref(), other.0.as_ref()) {
(Some(a), Some(b)) => a == b,
_ => false,
}
}
}
}