<commit_before>use std::borrow;
use std::error;
use std::fmt;
use std::result;

use super::ClonableError;
use super::BoxedError;
use super::Trace;

/// Convenience type alias for Liquid compiler errors
pub type Result<T> = result::Result<T, Error>;

/// `Result` extension methods for adapting third party errors to `Error`.
pub trait ResultLiquidChainExt<T> {
    /// Create an `Error` with `E` as the cause.
    fn chain(self, msg: &'static str) -> Result<T>;
    /// Create an `Error` with `E` as the cause.
    fn chain_with<F>(self, msg: F) -> Result<T>
    where
        F: FnOnce() -> String;
}

impl<T, E> ResultLiquidChainExt<T> for result::Result<T, E>
where
    E: error::Error + Send + Sync + 'static,
{
    fn chain(self, msg: &'static str) -> Result<T> {
        self.map_err(|err| Error::with_msg(msg).cause(err))
    }

    fn chain_with<F>(self, msg: F) -> Result<T>
    where
        F: FnOnce() -> String,
    {
        self.map_err(|err| Error::with_msg(msg()).cause(err))
    }
}

/// Add context to a `liquid_error::Error`.
pub trait ResultLiquidExt<T> {
    /// Add a new stack frame to the `liquid_error::Error`.
    fn trace<S>(self, trace: S) -> Result<T>
    where
        S: Into<borrow::Cow<'static, str>>;

    /// Add a new stack frame to the `liquid_error::Error`.
    fn trace_with<F>(self, trace: F) -> Result<T>
    where
        F: FnOnce() -> String;

    /// Add state the current stack frame.
    fn context<K, V>(self, key: K, value: V) -> Result<T>
    where
        K: Into<borrow::Cow<'static, str>>,
        V: Into<borrow::Cow<'static, str>>;

    /// Add state the current stack frame.
    fn context_with<F>(self, context: F) -> Result<T>
    where
        F: FnOnce() -> (String, String);
}

impl<T> ResultLiquidExt<T> for Result<T> {
    fn trace<S>(self, trace: S) -> Result<T>
    where
        S: Into<borrow::Cow<'static, str>>,
    {
        self.map_err(|err| err.trace(trace))
    }

    fn trace_with<F>(self, trace: F) -> Result<T>
    where
        F: FnOnce() -> String,
    {
        self.map_err(|err| err.trace(trace()))
    }

    fn context<K, V>(self, key: K, value: V) -> Result<T>
    where
        K: Into<borrow::Cow<'static, str>>,
        V: Into<borrow::Cow<'static, str>>,
    {
        self.map_err(|err| err.context(key, value))
    }

    fn context_with<F>(self, context: F) -> Result<T>
    where
        F: FnOnce() -> (String, String),
    {
        let (key, value) = context();
        self.map_err(|err| err.context(key, value))
    }
}

/// Compiler error
#[derive(Clone, Debug)]
pub struct Error {
    inner: Box<InnerError>,
}

// Guts of `Error` here to keep `Error` small to avoid bloating the size of `Result<T>` in the
// success case.  There are already enough memory allocations below, one more shouldn't hurt.
#[derive(Clone, Debug)]
struct InnerError {
    msg: borrow::Cow<'static, str>,
    user_backtrace: Vec<Trace>,
    cause: Option<ClonableError>,
}

impl Error {
    /// Create a new compiler error with the given message
    pub fn with_msg<S: Into<borrow::Cow<'static, str>>>(msg: S) -> Self {
        Self::with_msg_cow(msg.into())
    }

    fn with_msg_cow(msg: borrow::Cow<'static, str>) -> Self {
        let error = InnerError {<commit_msg>chore: Clarify internal documentation<commit_after>use std::borrow;
use std::error;
use std::fmt;
use std::result;

use super::ClonableError;
use super::BoxedError;
use super::Trace;

/// Convenience type alias for Liquid compiler errors
pub type Result<T> = result::Result<T, Error>;

/// `Result` extension methods for adapting third party errors to `Error`.
pub trait ResultLiquidChainExt<T> {
    /// Create an `Error` with `E` as the cause.
    fn chain(self, msg: &'static str) -> Result<T>;
    /// Create an `Error` with `E` as the cause.
    fn chain_with<F>(self, msg: F) -> Result<T>
    where
        F: FnOnce() -> String;
}

impl<T, E> ResultLiquidChainExt<T> for result::Result<T, E>
where
    E: error::Error + Send + Sync + 'static,
{
    fn chain(self, msg: &'static str) -> Result<T> {
        self.map_err(|err| Error::with_msg(msg).cause(err))
    }

    fn chain_with<F>(self, msg: F) -> Result<T>
    where
        F: FnOnce() -> String,
    {
        self.map_err(|err| Error::with_msg(msg()).cause(err))
    }
}

/// Add context to a `liquid_error::Error`.
pub trait ResultLiquidExt<T> {
    /// Add a new stack frame to the `liquid_error::Error`.
    fn trace<S>(self, trace: S) -> Result<T>
    where
        S: Into<borrow::Cow<'static, str>>;

    /// Add a new stack frame to the `liquid_error::Error`.
    fn trace_with<F>(self, trace: F) -> Result<T>
    where
        F: FnOnce() -> String;

    /// Add state the current stack frame.
    fn context<K, V>(self, key: K, value: V) -> Result<T>
    where
        K: Into<borrow::Cow<'static, str>>,
        V: Into<borrow::Cow<'static, str>>;

    /// Add state the current stack frame.
    fn context_with<F>(self, context: F) -> Result<T>
    where
        F: FnOnce() -> (String, String);
}

impl<T> ResultLiquidExt<T> for Result<T> {
    fn trace<S>(self, trace: S) -> Result<T>
    where
        S: Into<borrow::Cow<'static, str>>,
    {
        self.map_err(|err| err.trace(trace))
    }

    fn trace_with<F>(self, trace: F) -> Result<T>
    where
        F: FnOnce() -> String,
    {
        self.map_err(|err| err.trace(trace()))
    }

    fn context<K, V>(self, key: K, value: V) -> Result<T>
    where
        K: Into<borrow::Cow<'static, str>>,
        V: Into<borrow::Cow<'static, str>>,
    {
        self.map_err(|err| err.context(key, value))
    }

    fn context_with<F>(self, context: F) -> Result<T>
    where
        F: FnOnce() -> (String, String),
    {
        let (key, value) = context();
        self.map_err(|err| err.context(key, value))
    }
}

/// Compiler error
#[derive(Clone, Debug)]
pub struct Error {
    inner: Box<InnerError>,
}

// Guts of `Error` here to keep `Error`'s memory size small to avoid bloating the size of
// `Result<T>` in the success case and spilling over from register-based returns to stack-based
// returns.  There are already enough memory allocations below, one more
// shouldn't hurt.
#[derive(Clone, Debug)]
struct InnerError {
    msg: borrow::Cow<'static, str>,
    user_backtrace: Vec<Trace>,
    cause: Option<ClonableError>,
}

impl Error {
    /// Create a new compiler error with the given message
    pub fn with_msg<S: Into<borrow::Cow<'static, str>>>(msg: S) -> Self {
        Self::with_msg_cow(msg.into())
    }

    fn with_msg_cow(msg: borrow::Cow<'static, str>) -> Self {
        let error = InnerError {
{'fraction_non_alphanumeric': 0.16326530612244897, 'fraction_numerical': 0.0, 'mean_word_length': 2.871269748390872, 'pattern_counts': {'":': 0, '<': 109, '<?xml version=': 0, '>': 149, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5276181', 'n_tokens_mistral': 2335, 'n_tokens_neox': 2320, 'n_words': 650}