1
1
// Copyright Metatype OÜ, licensed under the Mozilla Public License Version 2.0.
2
2
// SPDX-License-Identifier: MPL-2.0
3
3
4
- use tg_schema :: InjectionNode ;
4
+ use crate :: { injection :: InjectionNode , interlude :: * , Type , TypeNodeExt as _ , Wrap } ;
5
5
6
- use crate :: { interlude :: * , Type , TypeNodeExt as _ , Wrap as _ } ;
6
+ use super :: { key :: TypeKeyEx , ConversionMap , MapItem , PathSegment , RelativePath , TypeKey } ;
7
7
8
- use super :: { ConversionMap , MapItem , RelativePath , TypeKey } ;
8
+ // TODO rename to `DuplicationKey`
9
+ pub trait DupKey : std:: hash:: Hash + Eq + Clone {
10
+ fn is_default ( & self ) -> bool ;
11
+ }
12
+
13
+ pub trait DuplicationKeyGenerator : Clone {
14
+ type Key : DupKey ;
15
+
16
+ fn gen_from_rpath ( & self , rpath : & RelativePath ) -> Self :: Key ;
17
+ fn gen_from_type ( & self , ty : & Type ) -> Self :: Key ;
18
+
19
+ fn apply_path_segment ( & self , key : & Self :: Key , path_seg : & PathSegment ) -> Self :: Key ;
20
+
21
+ fn find_type_in_rpath (
22
+ & self ,
23
+ ty : & Type ,
24
+ rpath : & RelativePath ,
25
+ schema : & tg_schema:: Typegraph ,
26
+ ) -> bool {
27
+ use RelativePath as RP ;
28
+ match rpath {
29
+ RP :: Function ( _) => false ,
30
+ RP :: NsObject ( _) => false ,
31
+ RP :: Input ( p) => {
32
+ let owner = p. owner . upgrade ( ) . expect ( "no strong pointer for type" ) ;
33
+ let input_type = match & schema. types [ owner. base . key . 0 as usize ] {
34
+ tg_schema:: TypeNode :: Function { data, .. } => data. input ,
35
+ _ => unreachable ! ( "expected a function node" ) ,
36
+ } ;
37
+ let xkey = TypeKeyEx ( ty. idx ( ) , self . gen_from_type ( ty) ) ;
38
+ let mut cursor = TypeKeyEx (
39
+ input_type,
40
+ self . gen_from_rpath ( & RelativePath :: input ( Arc :: downgrade ( & owner) , vec ! [ ] ) ) ,
41
+ ) ;
42
+ // let mut cursor = TypeKeyEx(input_type, DuplicationKey { injection });
43
+ for seg in & p. path {
44
+ let next_dkey = self . apply_path_segment ( & cursor. 1 , seg) ;
45
+ // FIXME why unwrap?
46
+ let idx = seg. apply_on_schema_node ( & schema. types , cursor. 0 ) . unwrap ( ) ;
47
+ let next = TypeKeyEx ( idx, next_dkey) ;
48
+ if next == xkey {
49
+ return true ;
50
+ }
51
+ cursor = next;
52
+ }
53
+
54
+ false
55
+ }
56
+
57
+ RP :: Output ( p) => {
58
+ let owner = p. owner . upgrade ( ) . expect ( "no strong pointer for type" ) ;
59
+ let out_ty = match & schema. types [ owner. base . key . 0 as usize ] {
60
+ tg_schema:: TypeNode :: Function { data, .. } => data. output ,
61
+ _ => unreachable ! ( "expected a function node" ) ,
62
+ } ;
63
+
64
+ let xkey = TypeKeyEx ( ty. idx ( ) , self . gen_from_type ( ty) ) ;
65
+
66
+ let mut cursor = TypeKeyEx (
67
+ out_ty,
68
+ self . gen_from_rpath ( & RelativePath :: output ( Arc :: downgrade ( & owner) , vec ! [ ] ) ) ,
69
+ ) ;
70
+ for seg in & p. path {
71
+ let next_dkey = self . apply_path_segment ( & cursor. 1 , seg) ;
72
+ let idx = seg. apply_on_schema_node ( & schema. types , cursor. 0 ) . unwrap ( ) ;
73
+ let next = TypeKeyEx ( idx, next_dkey) ;
74
+ if next == xkey {
75
+ return true ;
76
+ }
77
+ cursor = next;
78
+ }
9
79
10
- #[ derive( Default , Debug , PartialEq , Eq , Hash ) ]
11
- pub struct DuplicationKey {
12
- pub injection : Option < InjectionNode > ,
80
+ false
81
+ }
82
+ }
83
+ }
13
84
}
14
85
15
- impl DuplicationKey {
16
- fn new ( ty : & Type ) -> Self {
17
- Self {
18
- injection : ty. injection ( ) . cloned ( ) ,
86
+ #[ derive( Default , Clone , Debug , PartialEq , Eq , Hash ) ]
87
+ pub struct DefaultDuplicationKey {
88
+ pub injection : Option < Arc < InjectionNode > > ,
89
+ }
90
+
91
+ #[ derive( Clone , Debug ) ]
92
+ pub struct DefaultDuplicationKeyGenerator ;
93
+
94
+ impl DuplicationKeyGenerator for DefaultDuplicationKeyGenerator {
95
+ type Key = DefaultDuplicationKey ;
96
+
97
+ fn gen_from_rpath ( & self , rpath : & RelativePath ) -> Self :: Key {
98
+ Self :: Key {
99
+ injection : rpath. get_injection ( ) ,
19
100
}
20
101
}
21
102
22
- pub fn from_rpath ( schema : & tg_schema :: Typegraph , rpath : & RelativePath ) -> Self {
23
- Self {
24
- injection : rpath . get_injection ( schema ) ,
103
+ fn gen_from_type ( & self , ty : & Type ) -> Self :: Key {
104
+ Self :: Key {
105
+ injection : ty . injection ( ) ,
25
106
}
26
107
}
27
108
28
- pub fn is_empty ( & self ) -> bool {
109
+ fn apply_path_segment ( & self , key : & Self :: Key , path_seg : & PathSegment ) -> Self :: Key {
110
+ let inj = key
111
+ . injection
112
+ . as_ref ( )
113
+ . and_then ( |inj| path_seg. apply_on_injection ( inj) ) ;
114
+ Self :: Key { injection : inj }
115
+ }
116
+ }
117
+ impl DupKey for DefaultDuplicationKey {
118
+ fn is_default ( & self ) -> bool {
29
119
self . injection
30
120
. as_ref ( )
31
121
. map ( |inj| inj. is_empty ( ) )
32
122
. unwrap_or ( true )
33
123
}
34
124
}
35
125
36
- impl From < & Type > for DuplicationKey {
37
- fn from ( ty : & Type ) -> Self {
38
- Self :: new ( ty)
39
- }
40
- }
41
-
42
126
pub enum Deduplication {
43
127
/// a previously registered type was found
44
128
Reuse ( Type ) ,
@@ -55,12 +139,15 @@ impl Deduplication {
55
139
}
56
140
}
57
141
58
- impl ConversionMap {
59
- pub fn deduplicate ( & self , type_idx : u32 , dkey : & DuplicationKey ) -> Result < Deduplication > {
142
+ impl < DKG : DuplicationKeyGenerator > ConversionMap < DKG > {
143
+ pub fn deduplicate ( & self , type_idx : u32 , dkey : & DKG :: Key ) -> Result < Deduplication >
144
+ where
145
+ DKG : DuplicationKeyGenerator ,
146
+ {
60
147
match self . direct . get ( type_idx as usize ) {
61
148
Some ( MapItem :: Unset ) => Ok ( Deduplication :: register (
62
149
type_idx,
63
- match dkey. is_empty ( ) {
150
+ match dkey. is_default ( ) {
64
151
true => 0 ,
65
152
// Duplication key will always be empty for functions and namespaces;
66
153
// hence, this will always be valid.
@@ -72,7 +159,7 @@ impl ConversionMap {
72
159
}
73
160
Some ( MapItem :: Function ( fn_ty) ) => Ok ( Deduplication :: reuse ( fn_ty. wrap ( ) ) ) ,
74
161
Some ( MapItem :: Value ( value_type) ) => {
75
- if dkey. is_empty ( ) {
162
+ if dkey. is_default ( ) {
76
163
if let Some ( item) = value_type. default . as_ref ( ) {
77
164
Ok ( Deduplication :: reuse ( item. ty . clone ( ) ) )
78
165
} else {
0 commit comments