telety_impl/alias/
mod.rs

1mod details;
2pub(crate) use details::Details;
3mod index;
4pub(crate) use index::Index;
5mod map;
6pub(crate) use map::Map;
7mod group;
8pub(crate) use group::Group;
9
10use syn::{
11    punctuated::Punctuated, AngleBracketedGenericArguments, GenericArgument, Generics, Ident, Path,
12    PathArguments, PathSegment, Token, Type, TypePath,
13};
14
15use crate::syn_util;
16
17/// The details of a type alias.
18#[derive(Debug, Clone, Copy)]
19pub struct Alias<'m> {
20    map: &'m Map,
21    index: Index,
22    details: &'m Details,
23}
24
25impl<'m> Alias<'m> {
26    pub(crate) fn new(map: &'m Map, index: Index, details: &'m Details) -> Self {
27        Self {
28            map,
29            index,
30            details,
31        }
32    }
33
34    #[doc(hidden)]
35    pub fn ident(&self) -> Ident {
36        self.index.ident()
37    }
38
39    /// The generic parameters required for this type alias.  
40    /// For example, this item has two type parameters:  
41    /// ```rust,ignore
42    /// struct Either<A, B> {
43    ///     A(Box<A>),
44    ///     B(Box<B>),
45    /// }
46    /// ```
47    /// But reusing these parameters on the alias to the type in variant `A` will fail,
48    /// as parameter `B` is unused by the aliased type:
49    /// ```rust,ignore
50    /// type Alias<A, B> = Box<A>;
51    /// ```
52    /// ```text,ignore
53    /// type parameter `B` is unused
54    /// ```
55    /// This method returns only the generic parameters used by the alias.
56    pub fn parameters(&self) -> &Generics {
57        &self.details.parameters
58    }
59
60    /// Returns this alias formatted as a [PathSegment], without generic parameters
61    pub fn path_segment_no_parameters(&self) -> PathSegment {
62        PathSegment {
63            ident: self.index.ident(),
64            arguments: PathArguments::None,
65        }
66    }
67
68    /// Returns this alias formatted as a [PathSegment], with unsubstituted generic
69    /// arguments if applicable.
70    pub fn path_segment(&self) -> PathSegment {
71        let mut segment = self.path_segment_no_parameters();
72        segment.arguments = PathArguments::AngleBracketed(AngleBracketedGenericArguments {
73            colon2_token: None,
74            lt_token: Default::default(),
75            args: syn_util::generic_params_to_arguments(self.parameters()),
76            gt_token: Default::default(),
77        });
78        segment
79    }
80
81    /// The original type being aliased
82    pub fn aliased_type(&self) -> &Type {
83        &self.details.aliased_type
84    }
85
86    /// The type arguments on the original aliased type.  
87    /// e.g. `i32, u64` for `my_crate::MyType<i32, i64>`
88    pub fn aliased_type_arguments(&self) -> Option<&Punctuated<GenericArgument, Token![,]>> {
89        if let Type::Path(type_path) = self.aliased_type() {
90            if let Some(last_segment) = type_path.path.segments.last() {
91                if let PathArguments::AngleBracketed(angle_bracketed) = &last_segment.arguments {
92                    return Some(&angle_bracketed.args);
93                }
94            }
95        }
96        None
97    }
98
99    /// Creates a qualified [Path] to the alias with no generic arguments
100    pub fn path(&self) -> Path {
101        let mut path = self.map.group().path();
102        path.segments.push(self.path_segment_no_parameters());
103        path
104    }
105
106    /// Creates a qualified [TypePath] to the alias, with generic arguments.
107    pub fn type_path(&self) -> TypePath {
108        let mut path = self.map.group().path();
109        path.segments.push(self.path_segment());
110        TypePath { qself: None, path }
111    }
112
113    /// Creates a qualified [Type] of the alias.
114    pub fn ty(&self) -> Type {
115        Type::Path(self.type_path())
116    }
117}