133d722a9Sopenharmony_ciuse crate::syntax::{NamedType, Ty1, Type};
233d722a9Sopenharmony_ciuse proc_macro2::{Ident, Span};
333d722a9Sopenharmony_ciuse std::hash::{Hash, Hasher};
433d722a9Sopenharmony_ciuse syn::Token;
533d722a9Sopenharmony_ci
633d722a9Sopenharmony_ci#[derive(Copy, Clone, PartialEq, Eq, Hash)]
733d722a9Sopenharmony_cipub enum ImplKey<'a> {
833d722a9Sopenharmony_ci    RustBox(NamedImplKey<'a>),
933d722a9Sopenharmony_ci    RustVec(NamedImplKey<'a>),
1033d722a9Sopenharmony_ci    UniquePtr(NamedImplKey<'a>),
1133d722a9Sopenharmony_ci    SharedPtr(NamedImplKey<'a>),
1233d722a9Sopenharmony_ci    WeakPtr(NamedImplKey<'a>),
1333d722a9Sopenharmony_ci    CxxVector(NamedImplKey<'a>),
1433d722a9Sopenharmony_ci}
1533d722a9Sopenharmony_ci
1633d722a9Sopenharmony_ci#[derive(Copy, Clone)]
1733d722a9Sopenharmony_cipub struct NamedImplKey<'a> {
1833d722a9Sopenharmony_ci    pub begin_span: Span,
1933d722a9Sopenharmony_ci    pub rust: &'a Ident,
2033d722a9Sopenharmony_ci    pub lt_token: Option<Token![<]>,
2133d722a9Sopenharmony_ci    pub gt_token: Option<Token![>]>,
2233d722a9Sopenharmony_ci    pub end_span: Span,
2333d722a9Sopenharmony_ci}
2433d722a9Sopenharmony_ci
2533d722a9Sopenharmony_ciimpl Type {
2633d722a9Sopenharmony_ci    pub(crate) fn impl_key(&self) -> Option<ImplKey> {
2733d722a9Sopenharmony_ci        if let Type::RustBox(ty) = self {
2833d722a9Sopenharmony_ci            if let Type::Ident(ident) = &ty.inner {
2933d722a9Sopenharmony_ci                return Some(ImplKey::RustBox(NamedImplKey::new(ty, ident)));
3033d722a9Sopenharmony_ci            }
3133d722a9Sopenharmony_ci        } else if let Type::RustVec(ty) = self {
3233d722a9Sopenharmony_ci            if let Type::Ident(ident) = &ty.inner {
3333d722a9Sopenharmony_ci                return Some(ImplKey::RustVec(NamedImplKey::new(ty, ident)));
3433d722a9Sopenharmony_ci            }
3533d722a9Sopenharmony_ci        } else if let Type::UniquePtr(ty) = self {
3633d722a9Sopenharmony_ci            if let Type::Ident(ident) = &ty.inner {
3733d722a9Sopenharmony_ci                return Some(ImplKey::UniquePtr(NamedImplKey::new(ty, ident)));
3833d722a9Sopenharmony_ci            }
3933d722a9Sopenharmony_ci        } else if let Type::SharedPtr(ty) = self {
4033d722a9Sopenharmony_ci            if let Type::Ident(ident) = &ty.inner {
4133d722a9Sopenharmony_ci                return Some(ImplKey::SharedPtr(NamedImplKey::new(ty, ident)));
4233d722a9Sopenharmony_ci            }
4333d722a9Sopenharmony_ci        } else if let Type::WeakPtr(ty) = self {
4433d722a9Sopenharmony_ci            if let Type::Ident(ident) = &ty.inner {
4533d722a9Sopenharmony_ci                return Some(ImplKey::WeakPtr(NamedImplKey::new(ty, ident)));
4633d722a9Sopenharmony_ci            }
4733d722a9Sopenharmony_ci        } else if let Type::CxxVector(ty) = self {
4833d722a9Sopenharmony_ci            if let Type::Ident(ident) = &ty.inner {
4933d722a9Sopenharmony_ci                return Some(ImplKey::CxxVector(NamedImplKey::new(ty, ident)));
5033d722a9Sopenharmony_ci            }
5133d722a9Sopenharmony_ci        }
5233d722a9Sopenharmony_ci        None
5333d722a9Sopenharmony_ci    }
5433d722a9Sopenharmony_ci}
5533d722a9Sopenharmony_ci
5633d722a9Sopenharmony_ciimpl<'a> PartialEq for NamedImplKey<'a> {
5733d722a9Sopenharmony_ci    fn eq(&self, other: &Self) -> bool {
5833d722a9Sopenharmony_ci        PartialEq::eq(self.rust, other.rust)
5933d722a9Sopenharmony_ci    }
6033d722a9Sopenharmony_ci}
6133d722a9Sopenharmony_ci
6233d722a9Sopenharmony_ciimpl<'a> Eq for NamedImplKey<'a> {}
6333d722a9Sopenharmony_ci
6433d722a9Sopenharmony_ciimpl<'a> Hash for NamedImplKey<'a> {
6533d722a9Sopenharmony_ci    fn hash<H: Hasher>(&self, hasher: &mut H) {
6633d722a9Sopenharmony_ci        self.rust.hash(hasher);
6733d722a9Sopenharmony_ci    }
6833d722a9Sopenharmony_ci}
6933d722a9Sopenharmony_ci
7033d722a9Sopenharmony_ciimpl<'a> NamedImplKey<'a> {
7133d722a9Sopenharmony_ci    fn new(outer: &Ty1, inner: &'a NamedType) -> Self {
7233d722a9Sopenharmony_ci        NamedImplKey {
7333d722a9Sopenharmony_ci            begin_span: outer.name.span(),
7433d722a9Sopenharmony_ci            rust: &inner.rust,
7533d722a9Sopenharmony_ci            lt_token: inner.generics.lt_token,
7633d722a9Sopenharmony_ci            gt_token: inner.generics.gt_token,
7733d722a9Sopenharmony_ci            end_span: outer.rangle.span,
7833d722a9Sopenharmony_ci        }
7933d722a9Sopenharmony_ci    }
8033d722a9Sopenharmony_ci}
81