@@ -2,15 +2,17 @@ mod slice;
2
2
mod string;
3
3
mod vector;
4
4
5
- use std:: { ffi:: c_void, fmt:: Display , ptr:: NonNull } ;
5
+ use std:: { ffi:: c_void, fmt:: Display , mem :: MaybeUninit , ptr:: NonNull } ;
6
6
7
7
use resolvo:: { HintDependenciesAvailable , KnownDependencies , SolverCache } ;
8
8
9
9
use crate :: { slice:: Slice , string:: String , vector:: Vector } ;
10
10
11
- /// A unique identifier for a single solvable or candidate of a package. These ids should not be
12
- /// random but rather monotonic increasing. Although it is fine to have gaps, resolvo will
13
- /// allocate some memory based on the maximum id.
11
+ /// A unique identifier for a single solvable or candidate of a package. These
12
+ /// ids should not be random but rather monotonic increasing. Although it is
13
+ /// fine to have gaps, resolvo will allocate some memory based on the maximum
14
+ /// id.
15
+ ///
14
16
/// cbindgen:derive-eq
15
17
/// cbindgen:derive-neq
16
18
#[ repr( C ) ]
@@ -41,10 +43,11 @@ pub enum Requirement {
41
43
/// cbindgen:derive-eq
42
44
/// cbindgen:derive-neq
43
45
Single ( VersionSetId ) ,
44
- /// Specifies a dependency on the union (logical OR) of multiple version sets. A solvable
45
- /// belonging to ANY of the version sets contained in the union satisfies the requirement.
46
- /// This variant is typically used for requirements that can be satisfied by two or more
47
- /// version sets belonging to different packages.
46
+ /// Specifies a dependency on the union (logical OR) of multiple version
47
+ /// sets. A solvable belonging to ANY of the version sets contained in
48
+ /// the union satisfies the requirement. This variant is typically used
49
+ /// for requirements that can be satisfied by two or more version sets
50
+ /// belonging to different packages.
48
51
/// cbindgen:derive-eq
49
52
/// cbindgen:derive-neq
50
53
Union ( VersionSetUnionId ) ,
@@ -156,13 +159,120 @@ impl From<StringId> for resolvo::StringId {
156
159
}
157
160
}
158
161
162
+ /// A unique identifier for a single condition.
163
+ /// cbindgen:derive-eq
164
+ /// cbindgen:derive-neq
165
+ #[ repr( C ) ]
166
+ #[ derive( Copy , Clone ) ]
167
+ pub struct ConditionId {
168
+ id : u32 ,
169
+ }
170
+
171
+ impl From < resolvo:: ConditionId > for ConditionId {
172
+ fn from ( id : resolvo:: ConditionId ) -> Self {
173
+ Self { id : id. as_u32 ( ) }
174
+ }
175
+ }
176
+
177
+ impl From < ConditionId > for resolvo:: ConditionId {
178
+ fn from ( id : ConditionId ) -> Self {
179
+ Self :: new ( id. id )
180
+ }
181
+ }
182
+
183
+ /// Specifies the dependency of a solvable on a set of version sets.
184
+ /// cbindgen:derive-eq
185
+ /// cbindgen:derive-neq
186
+ #[ repr( C ) ]
187
+ #[ derive( Copy , Clone ) ]
188
+ pub enum Condition {
189
+ /// Specifies a dependency on a single version set.
190
+ ///
191
+ /// cbindgen:derive-eq
192
+ /// cbindgen:derive-neq
193
+ Requirement ( VersionSetId ) ,
194
+
195
+ /// Combines two conditions using a logical operator.
196
+ ///
197
+ /// cbindgen:derive-eq
198
+ /// cbindgen:derive-neq
199
+ Binary ( LogicalOperator , ConditionId , ConditionId ) ,
200
+ }
201
+
202
+ /// Defines how multiple conditions are compared to each other.
203
+ #[ repr( C ) ]
204
+ #[ derive( Copy , Clone ) ]
205
+ pub enum LogicalOperator {
206
+ And ,
207
+ Or ,
208
+ }
209
+
210
+ impl From < resolvo:: LogicalOperator > for LogicalOperator {
211
+ fn from ( value : resolvo:: LogicalOperator ) -> Self {
212
+ match value {
213
+ resolvo:: LogicalOperator :: And => LogicalOperator :: And ,
214
+ resolvo:: LogicalOperator :: Or => LogicalOperator :: Or ,
215
+ }
216
+ }
217
+ }
218
+
219
+ impl From < LogicalOperator > for resolvo:: LogicalOperator {
220
+ fn from ( value : LogicalOperator ) -> Self {
221
+ match value {
222
+ LogicalOperator :: And => resolvo:: LogicalOperator :: And ,
223
+ LogicalOperator :: Or => resolvo:: LogicalOperator :: Or ,
224
+ }
225
+ }
226
+ }
227
+
228
+ impl From < resolvo:: Condition > for Condition {
229
+ fn from ( value : resolvo:: Condition ) -> Self {
230
+ match value {
231
+ resolvo:: Condition :: Requirement ( id) => Condition :: Requirement ( id. into ( ) ) ,
232
+ resolvo:: Condition :: Binary ( op, lhs, rhs) => {
233
+ Condition :: Binary ( op. into ( ) , lhs. into ( ) , rhs. into ( ) )
234
+ }
235
+ }
236
+ }
237
+ }
238
+
239
+ impl From < Condition > for resolvo:: Condition {
240
+ fn from ( value : Condition ) -> Self {
241
+ match value {
242
+ Condition :: Requirement ( id) => resolvo:: Condition :: Requirement ( id. into ( ) ) ,
243
+ Condition :: Binary ( op, lhs, rhs) => {
244
+ resolvo:: Condition :: Binary ( op. into ( ) , lhs. into ( ) , rhs. into ( ) )
245
+ }
246
+ }
247
+ }
248
+ }
249
+
250
+ #[ derive( Clone ) ]
251
+ #[ repr( C ) ]
252
+ pub struct ConditionalRequirement {
253
+ /// Optionally a condition that indicates whether the requirement is enabled or not.
254
+ pub condition : * const ConditionId ,
255
+
256
+ /// A requirement on another package.
257
+ pub requirement : Requirement ,
258
+ }
259
+
260
+ impl From < ConditionalRequirement > for resolvo:: ConditionalRequirement {
261
+ fn from ( value : ConditionalRequirement ) -> Self {
262
+ Self {
263
+ condition : unsafe { value. condition . as_ref ( ) } . copied ( ) . map ( Into :: into) ,
264
+ requirement : value. requirement . into ( ) ,
265
+ }
266
+ }
267
+ }
268
+
159
269
#[ derive( Default ) ]
160
270
#[ repr( C ) ]
161
271
pub struct Dependencies {
162
272
/// A pointer to the first element of a list of requirements. Requirements
163
273
/// defines which packages should be installed alongside the depending
164
274
/// package and the constraints applied to the package.
165
- pub requirements : Vector < Requirement > ,
275
+ pub requirements : Vector < ConditionalRequirement > ,
166
276
167
277
/// Defines additional constraints on packages that may or may not be part
168
278
/// of the solution. Different from `requirements`, packages in this set
@@ -294,7 +404,12 @@ pub struct DependencyProvider {
294
404
pub version_sets_in_union : unsafe extern "C" fn (
295
405
data : * mut c_void ,
296
406
version_set_union_id : VersionSetUnionId ,
297
- ) -> Slice < ' static , VersionSetId > ,
407
+ result : NonNull < Slice < ' static , VersionSetId > > ,
408
+ ) ,
409
+
410
+ /// Returns the condition that the given condition id describes
411
+ pub resolve_condition :
412
+ unsafe extern "C" fn ( data : * mut c_void , condition : ConditionId , result : NonNull < Condition > ) ,
298
413
299
414
/// Obtains a list of solvables that should be considered when a package
300
415
/// with the given name is requested.
@@ -387,11 +502,32 @@ impl resolvo::Interner for &DependencyProvider {
387
502
& self ,
388
503
version_set_union : resolvo:: VersionSetUnionId ,
389
504
) -> impl Iterator < Item = resolvo:: VersionSetId > {
390
- unsafe { ( self . version_sets_in_union ) ( self . data , version_set_union. into ( ) ) }
391
- . as_slice ( )
392
- . iter ( )
393
- . copied ( )
394
- . map ( Into :: into)
505
+ let mut result = MaybeUninit :: uninit ( ) ;
506
+ unsafe {
507
+ ( self . version_sets_in_union ) (
508
+ self . data ,
509
+ version_set_union. into ( ) ,
510
+ NonNull :: new_unchecked ( result. as_mut_ptr ( ) ) ,
511
+ ) ;
512
+ result. assume_init ( )
513
+ }
514
+ . as_slice ( )
515
+ . iter ( )
516
+ . copied ( )
517
+ . map ( Into :: into)
518
+ }
519
+
520
+ fn resolve_condition ( & self , condition : resolvo:: ConditionId ) -> resolvo:: Condition {
521
+ let mut result = MaybeUninit :: uninit ( ) ;
522
+ unsafe {
523
+ ( self . resolve_condition ) (
524
+ self . data ,
525
+ condition. into ( ) ,
526
+ NonNull :: new_unchecked ( result. as_mut_ptr ( ) ) ,
527
+ ) ;
528
+ result. assume_init ( )
529
+ }
530
+ . into ( )
395
531
}
396
532
}
397
533
@@ -486,7 +622,7 @@ impl resolvo::DependencyProvider for &DependencyProvider {
486
622
487
623
#[ repr( C ) ]
488
624
pub struct Problem < ' a > {
489
- pub requirements : Slice < ' a , Requirement > ,
625
+ pub requirements : Slice < ' a , ConditionalRequirement > ,
490
626
pub constraints : Slice < ' a , VersionSetId > ,
491
627
pub soft_requirements : Slice < ' a , SolvableId > ,
492
628
}
@@ -507,7 +643,7 @@ pub extern "C" fn resolvo_solve(
507
643
. requirements
508
644
. as_slice ( )
509
645
. iter ( )
510
- . copied ( )
646
+ . cloned ( )
511
647
. map ( Into :: into)
512
648
. collect ( ) ,
513
649
)
@@ -545,20 +681,6 @@ pub extern "C" fn resolvo_solve(
545
681
}
546
682
}
547
683
548
- #[ unsafe( no_mangle) ]
549
- #[ allow( unused) ]
550
- pub extern "C" fn resolvo_requirement_single ( version_set_id : VersionSetId ) -> Requirement {
551
- Requirement :: Single ( version_set_id)
552
- }
553
-
554
- #[ unsafe( no_mangle) ]
555
- #[ allow( unused) ]
556
- pub extern "C" fn resolvo_requirement_union (
557
- version_set_union_id : VersionSetUnionId ,
558
- ) -> Requirement {
559
- Requirement :: Union ( version_set_union_id)
560
- }
561
-
562
684
#[ cfg( test) ]
563
685
mod tests {
564
686
use super :: * ;
0 commit comments