@@ -7,6 +7,37 @@ mod numpy;
77
88use maplit:: hashset;
99use std:: { collections:: HashSet , fmt, ops} ;
10+ use std:: cmp:: Ordering ;
11+
12+ #[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
13+ pub enum CommonRef {
14+ Module ( ModuleRef ) ,
15+ Type ( TypeRef ) ,
16+ }
17+
18+ impl PartialOrd for CommonRef {
19+ fn partial_cmp ( & self , other : & Self ) -> Option < Ordering > {
20+ Some ( self . cmp ( other) )
21+ }
22+ }
23+
24+
25+ impl Ord for CommonRef {
26+ fn cmp ( & self , other : & Self ) -> Ordering {
27+ match ( self , other) {
28+ ( CommonRef :: Module ( a) , CommonRef :: Module ( b) ) => a. get ( ) . cmp ( & b. get ( ) ) ,
29+ ( CommonRef :: Type ( a) , CommonRef :: Type ( b) ) => a. cmp ( b) ,
30+ ( CommonRef :: Module ( _) , CommonRef :: Type ( _) ) => Ordering :: Greater ,
31+ ( CommonRef :: Type ( _) , CommonRef :: Module ( _) ) => Ordering :: Less ,
32+ }
33+ }
34+ }
35+
36+ impl From < & str > for CommonRef {
37+ fn from ( s : & str ) -> Self {
38+ CommonRef :: Module ( s. into ( ) )
39+ }
40+ }
1041
1142#[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Ord , Default , Hash ) ]
1243pub enum ModuleRef {
@@ -39,6 +70,22 @@ impl From<&str> for ModuleRef {
3970 }
4071}
4172
73+
74+ /// Indicates the dependent type(eg class enum).
75+ /// from module import type.
76+ /// name, type name. module, module name(which type defined).
77+ #[ derive( Debug , Clone , PartialEq , Eq , PartialOrd , Ord , Default , Hash ) ]
78+ pub struct TypeRef {
79+ pub module : String ,
80+ pub name : String ,
81+ }
82+
83+ impl TypeRef {
84+ pub fn new ( module : String , name : String ) -> Self {
85+ Self { name, module}
86+ }
87+ }
88+
4289/// Type information for creating Python stub files annotated by [PyStubType] trait.
4390#[ derive( Debug , Clone , PartialEq , Eq ) ]
4491pub struct TypeInfo {
@@ -49,7 +96,7 @@ pub struct TypeInfo {
4996 ///
5097 /// For example, when `name` is `typing.Sequence[int]`, `import` should contain `typing`.
5198 /// This makes it possible to use user-defined types in the stub file.
52- pub import : HashSet < ModuleRef > ,
99+ pub import : HashSet < CommonRef > ,
53100}
54101
55102impl fmt:: Display for TypeInfo {
@@ -138,12 +185,35 @@ impl TypeInfo {
138185 /// ```
139186 pub fn with_module ( name : & str , module : ModuleRef ) -> Self {
140187 let mut import = HashSet :: new ( ) ;
141- import. insert ( module) ;
188+ import. insert ( CommonRef :: Module ( module) ) ;
142189 Self {
143190 name : name. to_string ( ) ,
144191 import,
145192 }
146193 }
194+
195+ /// A type annotation of a type that must be imported.
196+ ///
197+ /// ```
198+ /// ClassA defined in ModuleA
199+ /// pyo3_stub_gen::TypeInfo::with_type("ClassA", "ModuleA");
200+ /// ```
201+ pub fn with_type ( type_name : & str , module : ModuleRef ) -> Self {
202+ let mut import = HashSet :: new ( ) ;
203+ let mut module_name = String :: new ( ) ;
204+ match module. get ( ) {
205+ Some ( value) => module_name = value. to_string ( ) ,
206+ None => module_name = "" . to_string ( ) ,
207+ }
208+
209+ let type_ref = TypeRef :: new ( module_name, type_name. to_string ( ) ) ;
210+ import. insert ( CommonRef :: Type ( type_ref) ) ;
211+
212+ Self {
213+ name : type_name. to_string ( ) ,
214+ import,
215+ }
216+ }
147217}
148218
149219impl ops:: BitOr for TypeInfo {
@@ -244,7 +314,7 @@ mod test {
244314 #[ test_case( HashMap :: <u32 , Vec <u32 >>:: type_output( ) , "builtins.dict[builtins.int, builtins.list[builtins.int]]" , hashset! { "builtins" . into( ) } ; "HashMap_u32_Vec_u32_output" ) ]
245315 #[ test_case( HashSet :: <u32 >:: type_input( ) , "builtins.set[builtins.int]" , hashset! { "builtins" . into( ) } ; "HashSet_u32_input" ) ]
246316 #[ test_case( indexmap:: IndexSet :: <u32 >:: type_input( ) , "builtins.set[builtins.int]" , hashset! { "builtins" . into( ) } ; "IndexSet_u32_input" ) ]
247- fn test ( tinfo : TypeInfo , name : & str , import : HashSet < ModuleRef > ) {
317+ fn test ( tinfo : TypeInfo , name : & str , import : HashSet < CommonRef > ) {
248318 assert_eq ! ( tinfo. name, name) ;
249319 if import. is_empty ( ) {
250320 assert ! ( tinfo. import. is_empty( ) ) ;
0 commit comments