blob: b6cbf24b5c11f79cfc635d3fe0cdc278cc57dcff [file] [log] [blame]
David Tolnay9dab9d82021-03-27 01:46:01 -04001use crate::syntax::{NamedType, Ty1, Type};
2use proc_macro2::{Ident, Span};
David Tolnaydde63022021-03-26 22:22:35 -04003use std::hash::{Hash, Hasher};
4use syn::Token;
David Tolnay4c6052d2020-12-31 15:01:04 -08005
David Tolnaye352c1e2020-12-31 16:41:05 -08006#[derive(Copy, Clone, PartialEq, Eq, Hash)]
David Tolnay4c6052d2020-12-31 15:01:04 -08007pub enum ImplKey<'a> {
David Tolnaydde63022021-03-26 22:22:35 -04008 RustBox(NamedImplKey<'a>),
9 RustVec(NamedImplKey<'a>),
10 UniquePtr(NamedImplKey<'a>),
11 SharedPtr(NamedImplKey<'a>),
12 WeakPtr(NamedImplKey<'a>),
13 CxxVector(NamedImplKey<'a>),
14}
15
16#[derive(Copy, Clone)]
17pub struct NamedImplKey<'a> {
David Tolnay9dab9d82021-03-27 01:46:01 -040018 pub begin_span: Span,
David Tolnaydde63022021-03-26 22:22:35 -040019 pub rust: &'a Ident,
20 pub lt_token: Option<Token![<]>,
21 pub gt_token: Option<Token![>]>,
David Tolnay9dab9d82021-03-27 01:46:01 -040022 pub end_span: Span,
David Tolnay4c6052d2020-12-31 15:01:04 -080023}
24
25impl Type {
26 pub(crate) fn impl_key(&self) -> Option<ImplKey> {
27 if let Type::RustBox(ty) = self {
28 if let Type::Ident(ident) = &ty.inner {
David Tolnay9dab9d82021-03-27 01:46:01 -040029 return Some(ImplKey::RustBox(NamedImplKey::new(ty, ident)));
David Tolnay4c6052d2020-12-31 15:01:04 -080030 }
31 } else if let Type::RustVec(ty) = self {
32 if let Type::Ident(ident) = &ty.inner {
David Tolnay9dab9d82021-03-27 01:46:01 -040033 return Some(ImplKey::RustVec(NamedImplKey::new(ty, ident)));
David Tolnay4c6052d2020-12-31 15:01:04 -080034 }
35 } else if let Type::UniquePtr(ty) = self {
36 if let Type::Ident(ident) = &ty.inner {
David Tolnay9dab9d82021-03-27 01:46:01 -040037 return Some(ImplKey::UniquePtr(NamedImplKey::new(ty, ident)));
David Tolnay4c6052d2020-12-31 15:01:04 -080038 }
39 } else if let Type::SharedPtr(ty) = self {
40 if let Type::Ident(ident) = &ty.inner {
David Tolnay9dab9d82021-03-27 01:46:01 -040041 return Some(ImplKey::SharedPtr(NamedImplKey::new(ty, ident)));
David Tolnay4c6052d2020-12-31 15:01:04 -080042 }
43 } else if let Type::WeakPtr(ty) = self {
44 if let Type::Ident(ident) = &ty.inner {
David Tolnay9dab9d82021-03-27 01:46:01 -040045 return Some(ImplKey::WeakPtr(NamedImplKey::new(ty, ident)));
David Tolnay4c6052d2020-12-31 15:01:04 -080046 }
47 } else if let Type::CxxVector(ty) = self {
48 if let Type::Ident(ident) = &ty.inner {
David Tolnay9dab9d82021-03-27 01:46:01 -040049 return Some(ImplKey::CxxVector(NamedImplKey::new(ty, ident)));
David Tolnay4c6052d2020-12-31 15:01:04 -080050 }
51 }
52 None
53 }
54}
David Tolnaydde63022021-03-26 22:22:35 -040055
56impl<'a> PartialEq for NamedImplKey<'a> {
57 fn eq(&self, other: &Self) -> bool {
58 PartialEq::eq(self.rust, other.rust)
59 }
60}
61
62impl<'a> Eq for NamedImplKey<'a> {}
63
64impl<'a> Hash for NamedImplKey<'a> {
65 fn hash<H: Hasher>(&self, hasher: &mut H) {
66 self.rust.hash(hasher);
67 }
68}
69
David Tolnay9dab9d82021-03-27 01:46:01 -040070impl<'a> NamedImplKey<'a> {
71 fn new(outer: &Ty1, inner: &'a NamedType) -> Self {
David Tolnaydde63022021-03-26 22:22:35 -040072 NamedImplKey {
David Tolnay9dab9d82021-03-27 01:46:01 -040073 begin_span: outer.name.span(),
74 rust: &inner.rust,
75 lt_token: inner.generics.lt_token,
76 gt_token: inner.generics.gt_token,
77 end_span: outer.rangle.span,
David Tolnaydde63022021-03-26 22:22:35 -040078 }
79 }
80}