Key impls by an enum rather than by Type
diff --git a/syntax/instantiate.rs b/syntax/instantiate.rs
new file mode 100644
index 0000000..2891485
--- /dev/null
+++ b/syntax/instantiate.rs
@@ -0,0 +1,43 @@
+use crate::syntax::Type;
+use proc_macro2::Ident;
+
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
+pub enum ImplKey<'a> {
+    RustBox(&'a Ident),
+    RustVec(&'a Ident),
+    UniquePtr(&'a Ident),
+    SharedPtr(&'a Ident),
+    WeakPtr(&'a Ident),
+    CxxVector(&'a Ident),
+}
+
+impl Type {
+    pub(crate) fn impl_key(&self) -> Option<ImplKey> {
+        if let Type::RustBox(ty) = self {
+            if let Type::Ident(ident) = &ty.inner {
+                return Some(ImplKey::RustBox(&ident.rust));
+            }
+        } else if let Type::RustVec(ty) = self {
+            if let Type::Ident(ident) = &ty.inner {
+                return Some(ImplKey::RustVec(&ident.rust));
+            }
+        } else if let Type::UniquePtr(ty) = self {
+            if let Type::Ident(ident) = &ty.inner {
+                return Some(ImplKey::UniquePtr(&ident.rust));
+            }
+        } else if let Type::SharedPtr(ty) = self {
+            if let Type::Ident(ident) = &ty.inner {
+                return Some(ImplKey::SharedPtr(&ident.rust));
+            }
+        } else if let Type::WeakPtr(ty) = self {
+            if let Type::Ident(ident) = &ty.inner {
+                return Some(ImplKey::WeakPtr(&ident.rust));
+            }
+        } else if let Type::CxxVector(ty) = self {
+            if let Type::Ident(ident) = &ty.inner {
+                return Some(ImplKey::CxxVector(&ident.rust));
+            }
+        }
+        None
+    }
+}