nstree 1.0.0

construct branched 'namespace strings' for nested subcomponents, often for logging
Documentation
//! Module for implementing [`NamespacePath`] and [`RawNamespacePath`] on things that "have
//! multiple" [`NamespacePath`]/[`RawNamespacePath`] within them e.g. vecs, slices, arrays, etc.
//!
//! Basically anything that needs to be conceptually "flattened".
use super::{NamespaceComponentsHint, NamespacePath, RawNamespacePath};

impl<T: NamespacePath> NamespacePath for Option<T> {
    #[inline]
    fn components(&self) -> impl IntoIterator<Item = crate::NamespaceComponent<'_>> {
        self.as_ref().into_iter().flat_map(T::components)
    }

    #[inline]
    fn components_hint(&self) -> NamespaceComponentsHint {
        self.as_ref()
            .map(T::components_hint)
            .unwrap_or_else(NamespaceComponentsHint::empty)
    }
}

impl<T: RawNamespacePath> RawNamespacePath for Option<T> {
    #[inline]
    fn raw_components(&self) -> impl IntoIterator<Item = impl core::fmt::Display> {
        self.as_ref().into_iter().flat_map(T::raw_components)
    }
}

impl<L: NamespacePath, R: NamespacePath> NamespacePath for either::Either<L, R> {
    #[inline]
    fn components(&self) -> impl IntoIterator<Item = crate::NamespaceComponent<'_>> {
        match self {
            either::Either::Left(v) => either::Left(v.components().into_iter()),
            either::Either::Right(v) => either::Right(v.components().into_iter()),
        }
    }

    #[inline]
    fn components_hint(&self) -> NamespaceComponentsHint {
        either::for_both!(self, s => s.components_hint())
    }
}

impl<L: RawNamespacePath, R: RawNamespacePath> RawNamespacePath for either::Either<L, R> {
    #[inline]
    fn raw_components(&self) -> impl IntoIterator<Item = impl core::fmt::Display> {
        match self {
            either::Either::Left(l) => {
                either::Left(l.raw_components().into_iter().map(either::Left))
            }
            either::Either::Right(r) => {
                either::Right(r.raw_components().into_iter().map(either::Right))
            }
        }
    }
}

impl<T: NamespacePath> NamespacePath for [T] {
    #[inline]
    fn components(&self) -> impl IntoIterator<Item = crate::NamespaceComponent<'_>> {
        self.iter().flat_map(NamespacePath::components)
    }

    #[inline]
    fn components_hint(&self) -> super::NamespaceComponentsHint {
        self.iter()
            .map(NamespacePath::components_hint)
            .fold(NamespaceComponentsHint::empty(), |prev, add| {
                prev.with_appended(add)
            })
    }
}

impl<T: RawNamespacePath> RawNamespacePath for [T] {
    #[inline]
    fn raw_components(&self) -> impl IntoIterator<Item = impl core::fmt::Display> {
        self.iter().flat_map(RawNamespacePath::raw_components)
    }
}

impl<T: NamespacePath, const N: usize> NamespacePath for [T; N] {
    #[inline(always)]
    fn components(&self) -> impl IntoIterator<Item = crate::NamespaceComponent<'_>> {
        self.as_slice().components()
    }

    #[inline(always)]
    fn components_hint(&self) -> NamespaceComponentsHint {
        self.as_slice().components_hint()
    }
}

impl<T: RawNamespacePath, const N: usize> RawNamespacePath for [T; N] {
    #[inline(always)]
    fn raw_components(&self) -> impl IntoIterator<Item = impl core::fmt::Display> {
        self.as_slice().raw_components()
    }
}

#[cfg(any(feature = "alloc", test))]
impl<T: NamespacePath> NamespacePath for alloc::vec::Vec<T> {
    #[inline]
    fn components(&self) -> impl IntoIterator<Item = crate::NamespaceComponent<'_>> {
        self.as_slice().components()
    }

    #[inline]
    fn components_hint(&self) -> NamespaceComponentsHint {
        self.as_slice().components_hint()
    }
}

#[cfg(any(feature = "alloc", test))]
impl<T: RawNamespacePath> RawNamespacePath for alloc::vec::Vec<T> {
    #[inline]
    fn raw_components(&self) -> impl IntoIterator<Item = impl core::fmt::Display> {
        self.as_slice().raw_components()
    }
}

// nstree - nested namespace string-generating abstraction library
// Copyright (C) 2025  Matti <infomorphic-matti at protonmail dot com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
// ------
// SPDX-License-Identifier: GPL-3.0-or-later