accepts-codegen 0.0.1

Rust toolkit for composing synchronous and asynchronous acceptor pipelines
Documentation
use syn::{
    Ident, Path, PathArguments, PathSegment, punctuated::Punctuated, spanned::Spanned,
    token::PathSep,
};

use crate::common::syn::ext::{PathConstructExt, PathSegmentConstructExt};

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct PathSplitLastArgs {
    pub leading_colon: Option<PathSep>,
    pub segments: Punctuated<PathSegment, PathSep>,
    pub last_segment_ident: Ident,
}

#[allow(dead_code)]
impl PathSplitLastArgs {
    pub fn from_parts(
        leading_colon: Option<PathSep>,
        segments: Punctuated<PathSegment, PathSep>,
        last_segment_ident: Ident,
    ) -> Self {
        Self {
            leading_colon,
            segments,
            last_segment_ident,
        }
    }

    pub fn from_path(mut path: Path) -> syn::Result<(Self, PathArguments)> {
        if let Some(last_pair) = path.segments.pop() {
            let last = last_pair.into_value();
            Ok((
                Self::from_parts(path.leading_colon, path.segments, last.ident),
                last.arguments,
            ))
        } else {
            let msg = if path.leading_colon.is_some() {
                "expected a path segment after `::`"
            } else {
                "expected a non-empty path (at least one segment)"
            };
            Err(syn::Error::new(path.span(), msg))
        }
    }

    pub fn into_path(mut self, last_segment_arguments: PathArguments) -> Path {
        self.segments.push(PathSegment::from_parts(
            self.last_segment_ident,
            last_segment_arguments,
        ));
        Path::from_parts(self.leading_colon, self.segments)
    }
}