graphql-strip-sensitive-literals 0.2.0

redact PII literals from a GraphQL query AST before logging/usage reporting
Documentation
//! Configuration for [`strip_sensitive_literals`](crate::strip_sensitive_literals).

/// Controls how aggressively literals are redacted.
///
/// The default redacts scalar literals only. Scalars are integers, floats, and
/// strings. List and object literals keep their shape and the redactor recurses
/// into their elements.
///
/// Set [`hide_list_and_object_literals`](Self::hide_list_and_object_literals) to
/// `true` to also empty every list and object literal. An empty list or object
/// reveals nothing about the data it held, including its length and its keys.
///
/// An absent option and an explicit `false` behave the same. Only `true` turns
/// list and object emptying on.
///
/// # Construction
///
/// The struct is `#[non_exhaustive]`, so build it with [`StripOptions::default`]
/// or [`StripOptions::builder`] rather than a struct literal. New options can
/// then land in a minor release without breaking call sites. The fields stay
/// public for reading.
///
/// # Examples
///
/// ```
/// use graphql_strip_sensitive_literals::StripOptions;
///
/// // Default keeps list and object structure.
/// let keep = StripOptions::default();
/// assert!(!keep.hide_list_and_object_literals);
///
/// // Opt in to empty lists and objects.
/// let hide = StripOptions::builder()
///     .hide_list_and_object_literals(true)
///     .build();
/// assert!(hide.hide_list_and_object_literals);
/// ```
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub struct StripOptions {
    /// Empty every list and object literal when `true`.
    ///
    /// A list becomes `[]` and an object becomes `{}`. The redactor drops the
    /// contents and does not recurse into them. Default is `false`, which keeps
    /// the structure and redacts the nested scalars instead.
    pub hide_list_and_object_literals: bool,
}

impl StripOptions {
    /// Start building a [`StripOptions`] from the default configuration.
    ///
    /// ```
    /// use graphql_strip_sensitive_literals::StripOptions;
    ///
    /// let opts = StripOptions::builder()
    ///     .hide_list_and_object_literals(true)
    ///     .build();
    /// assert!(opts.hide_list_and_object_literals);
    /// ```
    pub fn builder() -> StripOptionsBuilder {
        StripOptionsBuilder {
            options: StripOptions::default(),
        }
    }
}

/// Builder for [`StripOptions`].
///
/// Created by [`StripOptions::builder`]. Each setter takes the builder by value
/// and returns it, so calls chain. Finish with [`build`](Self::build).
#[derive(Debug, Clone, Copy)]
pub struct StripOptionsBuilder {
    options: StripOptions,
}

impl StripOptionsBuilder {
    /// Empty every list and object literal when `true`.
    ///
    /// See [`StripOptions::hide_list_and_object_literals`].
    pub fn hide_list_and_object_literals(mut self, value: bool) -> Self {
        self.options.hide_list_and_object_literals = value;
        self
    }

    /// Return the configured [`StripOptions`].
    pub fn build(self) -> StripOptions {
        self.options
    }
}