@@ -4,18 +4,32 @@ use binrw::{binrw, BinRead, BinWrite, Endian, NullString};
4
4
5
5
use crate :: IxxError ;
6
6
7
- #[ binrw( magic = b"ixx01" , little) ]
8
- #[ derive( Default , Debug , Clone , PartialEq ) ]
7
+ #[ binrw]
8
+ #[ brw( magic = b"ixx01" ) ]
9
+ #[ derive( Debug , Clone , PartialEq ) ]
9
10
pub struct Index {
10
- #[ bw( calc = entries. len( ) as u32 ) ]
11
+ meta : Meta ,
12
+ #[ bw( calc = options. len( ) as u32 ) ]
11
13
count : u32 ,
12
14
#[ br( count = count) ]
13
- entries : Vec < Entry > ,
15
+ options : Vec < OptionEntry > ,
16
+ }
17
+
18
+ #[ binrw]
19
+ #[ derive( Debug , Clone , PartialEq ) ]
20
+ pub struct Meta {
21
+ pub chunk_size : u32 ,
22
+ #[ bw( calc = scopes. len( ) as u8 ) ]
23
+ scope_count : u8 ,
24
+ #[ br( count = scope_count) ]
25
+ pub scopes : Vec < NullString > ,
14
26
}
15
27
16
28
#[ binrw]
17
29
#[ derive( Default , Debug , Clone , PartialEq ) ]
18
- pub struct Entry {
30
+ pub struct OptionEntry {
31
+ /// index in the scopes Vec
32
+ scope_id : u8 ,
19
33
#[ bw( calc = labels. len( ) as u16 ) ]
20
34
count : u16 ,
21
35
#[ br( count = count) ]
@@ -32,11 +46,23 @@ struct Reference {
32
46
#[ binrw]
33
47
#[ derive( Debug , Clone , PartialEq ) ]
34
48
enum Label {
49
+ #[ brw( magic = b"0" ) ]
35
50
InPlace ( NullString ) ,
51
+ #[ brw( magic = b"1" ) ]
36
52
Reference ( Reference ) ,
37
53
}
38
54
39
55
impl Index {
56
+ pub fn new ( chunk_size : u32 ) -> Self {
57
+ Self {
58
+ meta : Meta {
59
+ chunk_size,
60
+ scopes : vec ! [ ] ,
61
+ } ,
62
+ options : vec ! [ ] ,
63
+ }
64
+ }
65
+
40
66
pub fn read ( buf : & [ u8 ] ) -> Result < Self , IxxError > {
41
67
Self :: read_from ( & mut Cursor :: new ( buf) )
42
68
}
@@ -49,13 +75,13 @@ impl Index {
49
75
Ok ( BinWrite :: write_options ( self , write, Endian :: Little , ( ) ) ?)
50
76
}
51
77
52
- pub fn push ( & mut self , option : & str ) {
78
+ pub fn push ( & mut self , scope_id : u8 , option : & str ) {
53
79
let labels = option
54
80
. split ( '.' )
55
81
. map ( |segment| {
56
82
let segment = segment. into ( ) ;
57
83
58
- for ( option_idx, Entry { labels : option } ) in self . entries . iter ( ) . enumerate ( ) {
84
+ for ( option_idx, OptionEntry { labels : option, .. } ) in self . options . iter ( ) . enumerate ( ) {
59
85
for ( label_idx, label) in option. iter ( ) . enumerate ( ) {
60
86
if let Label :: InPlace ( inplace) = label {
61
87
if inplace != & segment {
@@ -74,17 +100,17 @@ impl Index {
74
100
} )
75
101
. collect ( ) ;
76
102
77
- self . entries . push ( Entry { labels } ) ;
103
+ self . options . push ( OptionEntry { scope_id , labels } ) ;
78
104
}
79
105
80
106
fn resolve_reference ( & self , reference : & Reference ) -> Result < & NullString , IxxError > {
81
107
let option_idx = reference. option_idx as usize ;
82
108
83
- if self . entries . len ( ) <= option_idx {
109
+ if self . options . len ( ) <= option_idx {
84
110
return Err ( IxxError :: ReferenceOutOfBounds ) ;
85
111
}
86
112
87
- let entry = & self . entries [ option_idx] . labels ;
113
+ let entry = & self . options [ option_idx] . labels ;
88
114
89
115
let label_idx = reference. label_idx as usize ;
90
116
@@ -106,7 +132,7 @@ impl Index {
106
132
let segment = segment. into ( ) ;
107
133
108
134
' outer: {
109
- for ( option_idx, Entry { labels : option } ) in self . entries . iter ( ) . enumerate ( ) {
135
+ for ( option_idx, OptionEntry { labels : option, .. } ) in self . options . iter ( ) . enumerate ( ) {
110
136
for ( label_idx, label) in option. iter ( ) . enumerate ( ) {
111
137
if let Label :: InPlace ( inplace) = label {
112
138
if inplace != & segment {
@@ -128,27 +154,41 @@ impl Index {
128
154
129
155
Ok (
130
156
self
131
- . entries
157
+ . options
132
158
. iter ( )
133
159
. enumerate ( )
134
- . find ( |( idx, Entry { labels : option } ) | do_labels_match ( * idx, option, & labels) )
160
+ . find ( |( idx, OptionEntry { labels : option, .. } ) | do_labels_match ( * idx, option, & labels) )
135
161
. map ( |( idx, _) | idx) ,
136
162
)
137
163
}
138
164
139
- pub fn search ( & self , query : & str , max_results : usize ) -> Result < Vec < ( usize , String ) > , IxxError > {
165
+ pub fn search (
166
+ & self ,
167
+ scope_id : Option < u8 > ,
168
+ query : & str ,
169
+ max_results : usize ,
170
+ ) -> Result < Vec < ( usize , String ) > , IxxError > {
140
171
let search = query
141
172
. split ( '*' )
142
173
. map ( |segment| segment. to_lowercase ( ) )
143
174
. collect :: < Vec < _ > > ( ) ;
144
175
145
- if search. is_empty ( ) {
146
- return Ok ( vec ! [ ] ) ;
147
- }
148
-
149
176
let mut results = Vec :: new ( ) ;
150
177
151
- for ( idx, Entry { labels : option } ) in self . entries . iter ( ) . enumerate ( ) {
178
+ for (
179
+ idx,
180
+ OptionEntry {
181
+ scope_id : option_scope_id,
182
+ labels : option,
183
+ } ,
184
+ ) in self . options . iter ( ) . enumerate ( )
185
+ {
186
+ if let Some ( scope_id) = scope_id {
187
+ if * option_scope_id != scope_id {
188
+ continue ;
189
+ }
190
+ }
191
+
152
192
let mut option_name = String :: new ( ) ;
153
193
for label in option {
154
194
option_name. push_str ( & String :: try_from (
@@ -185,28 +225,18 @@ impl Index {
185
225
Ok ( results)
186
226
}
187
227
188
- pub fn all ( & self , max : usize ) -> Result < Vec < String > , IxxError > {
189
- let mut options = Vec :: new ( ) ;
190
-
191
- for Entry { labels : option } in & self . entries [ ..max] {
192
- let mut option_name = String :: new ( ) ;
193
- for label in option {
194
- option_name. push_str ( & String :: try_from (
195
- match label {
196
- Label :: InPlace ( data) => data,
197
- Label :: Reference ( reference) => self . resolve_reference ( reference) ?,
198
- }
199
- . clone ( ) ,
200
- ) ?) ;
201
- option_name. push ( '.' )
202
- }
203
- // remove last dot...
204
- option_name. pop ( ) ;
228
+ pub fn meta ( & self ) -> & Meta {
229
+ & self . meta
230
+ }
205
231
206
- options. push ( option_name) ;
232
+ pub fn push_scope ( & mut self , scope : String ) -> u8 {
233
+ if self . meta . scopes . len ( ) == u8:: MAX . into ( ) {
234
+ panic ! ( "You reached the limit of 256 scopes. Please contact the developers for further assistance." ) ;
207
235
}
208
236
209
- Ok ( options)
237
+ let idx = self . meta . scopes . len ( ) ;
238
+ self . meta . scopes . push ( scope. into ( ) ) ;
239
+ idx as u8
210
240
}
211
241
}
212
242
0 commit comments