@@ -2,15 +2,17 @@ mod slice;
22mod string;
33mod vector;
44
5- use std:: { ffi:: c_void, fmt:: Display , ptr:: NonNull } ;
5+ use std:: { ffi:: c_void, fmt:: Display , mem :: MaybeUninit , ptr:: NonNull } ;
66
77use resolvo:: { HintDependenciesAvailable , KnownDependencies , SolverCache } ;
88
99use crate :: { slice:: Slice , string:: String , vector:: Vector } ;
1010
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+ ///
1416/// cbindgen:derive-eq
1517/// cbindgen:derive-neq
1618#[ repr( C ) ]
@@ -41,10 +43,11 @@ pub enum Requirement {
4143 /// cbindgen:derive-eq
4244 /// cbindgen:derive-neq
4345 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.
4851 /// cbindgen:derive-eq
4952 /// cbindgen:derive-neq
5053 Union ( VersionSetUnionId ) ,
@@ -156,13 +159,120 @@ impl From<StringId> for resolvo::StringId {
156159 }
157160}
158161
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+
159269#[ derive( Default ) ]
160270#[ repr( C ) ]
161271pub struct Dependencies {
162272 /// A pointer to the first element of a list of requirements. Requirements
163273 /// defines which packages should be installed alongside the depending
164274 /// package and the constraints applied to the package.
165- pub requirements : Vector < Requirement > ,
275+ pub requirements : Vector < ConditionalRequirement > ,
166276
167277 /// Defines additional constraints on packages that may or may not be part
168278 /// of the solution. Different from `requirements`, packages in this set
@@ -294,7 +404,12 @@ pub struct DependencyProvider {
294404 pub version_sets_in_union : unsafe extern "C" fn (
295405 data : * mut c_void ,
296406 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 > ) ,
298413
299414 /// Obtains a list of solvables that should be considered when a package
300415 /// with the given name is requested.
@@ -387,11 +502,32 @@ impl resolvo::Interner for &DependencyProvider {
387502 & self ,
388503 version_set_union : resolvo:: VersionSetUnionId ,
389504 ) -> 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 ( )
395531 }
396532}
397533
@@ -486,7 +622,7 @@ impl resolvo::DependencyProvider for &DependencyProvider {
486622
487623#[ repr( C ) ]
488624pub struct Problem < ' a > {
489- pub requirements : Slice < ' a , Requirement > ,
625+ pub requirements : Slice < ' a , ConditionalRequirement > ,
490626 pub constraints : Slice < ' a , VersionSetId > ,
491627 pub soft_requirements : Slice < ' a , SolvableId > ,
492628}
@@ -507,7 +643,7 @@ pub extern "C" fn resolvo_solve(
507643 . requirements
508644 . as_slice ( )
509645 . iter ( )
510- . copied ( )
646+ . cloned ( )
511647 . map ( Into :: into)
512648 . collect ( ) ,
513649 )
@@ -545,20 +681,6 @@ pub extern "C" fn resolvo_solve(
545681 }
546682}
547683
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-
562684#[ cfg( test) ]
563685mod tests {
564686 use super :: * ;
0 commit comments