gurobirs 0.0.2

A Rust-API resembling the C++ API of the Gurobi Optimizer.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
use crate::{ffi, model::EnvSetter};
use std::ffi::{CStr, CString};

#[allow(clippy::upper_case_acronyms)]
#[derive(Clone, Copy)]
pub enum GRBIntParam {
    INHERITPARAMS,
    FUNCNONLINEAR,
    FUNCPIECES,
    PARTITIONPLACE,
    STARTNUMBER,
    IGNORENAMES,
    POOLSEARCHMODE,
    POOLSOLUTIONS,
    SCENARIONUMBER,
    MULTIOBJPRE,
    MULTIOBJMETHOD,
    OBJPASSNUMBER,
    OBJNUMBER,
    UPDATEMODE,
    TUNEDYNAMICJOBS,
    TUNEMETRIC,
    TUNEJOBS,
    TUNEOUTPUT,
    TUNETRIALS,
    TUNECRITERION,
    TUNERESULTS,
    THREADLIMIT,
    THREADS,
    SOLUTIONTARGET,
    SEED,
    RECORD,
    QCPDUAL,
    PREMIQCPFORM,
    PRESPARSIFY,
    PRESOS2ENCODING,
    PRESOS1ENCODING,
    PRESOLVE,
    PREQLINEARIZE,
    PREPASSES,
    PREDUAL,
    PREDEPROW,
    PRECRUSH,
    OUTPUTFLAG,
    NUMERICFOCUS,
    NONCONVEX,
    MIQCPMETHOD,
    LOGTOCONSOLE,
    LAZYCONSTRAINTS,
    JSONSOLDETAIL,
    INFUNBDINFO,
    IISMETHOD,
    DUALREDUCTIONS,
    DISTRIBUTEDMIPJOBS,
    DISPLAYINTERVAL,
    CONCURRENTJOBS,
    CONCURRENTMIP,
    AGGFILL,
    AGGREGATE,
    OPTIMALITYTARGET,
    LICENSEID,
    WLSTOKENDURATION,
    CSCLIENTLOG,
    CSBATCHMODE,
    TSPORT,
    CSTLSINSECURE,
    CSIDLETIMEOUT,
    CSPRIORITY,
    SERVERTIMEOUT,
    GOMORYPASSES,
    CUTPASSES,
    CUTAGGPASSES,
    MASTERKNAPSACKCUTS,
    DUALIMPLIEDCUTS,
    MIXINGCUTS,
    LIFTPROJECTCUTS,
    PSDCUTS,
    BQPCUTS,
    RELAXLIFTCUTS,
    RLTCUTS,
    INFPROOFCUTS,
    SUBMIPCUTS,
    NETWORKCUTS,
    ZEROHALFCUTS,
    MODKCUTS,
    STRONGCGCUTS,
    MIRCUTS,
    MIPSEPCUTS,
    PROJIMPLIEDCUTS,
    IMPLIEDCUTS,
    GUBCOVERCUTS,
    FLOWPATHCUTS,
    FLOWCOVERCUTS,
    COVERCUTS,
    CLIQUECUTS,
    CUTS,
    ZEROOBJNODES,
    SOLUTIONNUMBER,
    VARBRANCH,
    SYMMETRY,
    SUBMIPNODES,
    STARTNODELIMIT,
    RINS,
    PUMPPASSES,
    OBBT,
    NORELHEURSOLUTIONS,
    NODEMETHOD,
    NLPHEUR,
    MIPFOCUS,
    MINRELNODES,
    INTEGRALITYFOCUS,
    FIXVARSININDICATORS,
    DISCONNECTED,
    DEGENMOVES,
    BRANCHDIR,
    PDHGGPU,
    CROSSOVERBASIS,
    CROSSOVER,
    BARORDER,
    BARHOMOGENEOUS,
    BARCORRECTORS,
    NETWORKALG,
    LPWARMSTART,
    SIFTMETHOD,
    SIFTING,
    NORMADJUST,
    QUAD,
    SIMPLEXPRICING,
    SCALEFLAG,
    CONCURRENTMETHOD,
    METHOD,
    NLBARITERLIMIT,
    SOLUTIONLIMIT,
    BARITERLIMIT,
}

impl EnvSetter for GRBIntParam {
    type Value = i32;

    fn set(&self, env: *mut ffi::GRBenv, value: Self::Value) -> i32 {
        let attr_name: &CStr = (*self).into();
        unsafe { ffi::GRBsetintparam(env, attr_name.as_ptr(), value) }
    }
}

impl From<GRBIntParam> for &'static CStr {
    fn from(value: GRBIntParam) -> &'static CStr {
        match value {
            GRBIntParam::INHERITPARAMS => ffi::GRB_INT_PAR_INHERITPARAMS,
            GRBIntParam::FUNCNONLINEAR => ffi::GRB_INT_PAR_FUNCNONLINEAR,
            GRBIntParam::FUNCPIECES => ffi::GRB_INT_PAR_FUNCPIECES,
            GRBIntParam::PARTITIONPLACE => ffi::GRB_INT_PAR_PARTITIONPLACE,
            GRBIntParam::STARTNUMBER => ffi::GRB_INT_PAR_STARTNUMBER,
            GRBIntParam::IGNORENAMES => ffi::GRB_INT_PAR_IGNORENAMES,
            GRBIntParam::POOLSEARCHMODE => ffi::GRB_INT_PAR_POOLSEARCHMODE,
            GRBIntParam::POOLSOLUTIONS => ffi::GRB_INT_PAR_POOLSOLUTIONS,
            GRBIntParam::SCENARIONUMBER => ffi::GRB_INT_PAR_SCENARIONUMBER,
            GRBIntParam::MULTIOBJPRE => ffi::GRB_INT_PAR_MULTIOBJPRE,
            GRBIntParam::MULTIOBJMETHOD => ffi::GRB_INT_PAR_MULTIOBJMETHOD,
            GRBIntParam::OBJPASSNUMBER => ffi::GRB_INT_PAR_OBJPASSNUMBER,
            GRBIntParam::OBJNUMBER => ffi::GRB_INT_PAR_OBJNUMBER,
            GRBIntParam::UPDATEMODE => ffi::GRB_INT_PAR_UPDATEMODE,
            GRBIntParam::TUNEDYNAMICJOBS => ffi::GRB_INT_PAR_TUNEDYNAMICJOBS,
            GRBIntParam::TUNEMETRIC => ffi::GRB_INT_PAR_TUNEMETRIC,
            GRBIntParam::TUNEJOBS => ffi::GRB_INT_PAR_TUNEJOBS,
            GRBIntParam::TUNEOUTPUT => ffi::GRB_INT_PAR_TUNEOUTPUT,
            GRBIntParam::TUNETRIALS => ffi::GRB_INT_PAR_TUNETRIALS,
            GRBIntParam::TUNECRITERION => ffi::GRB_INT_PAR_TUNECRITERION,
            GRBIntParam::TUNERESULTS => ffi::GRB_INT_PAR_TUNERESULTS,
            GRBIntParam::THREADLIMIT => ffi::GRB_INT_PAR_THREADLIMIT,
            GRBIntParam::THREADS => ffi::GRB_INT_PAR_THREADS,
            GRBIntParam::SOLUTIONTARGET => ffi::GRB_INT_PAR_SOLUTIONTARGET,
            GRBIntParam::SEED => ffi::GRB_INT_PAR_SEED,
            GRBIntParam::RECORD => ffi::GRB_INT_PAR_RECORD,
            GRBIntParam::QCPDUAL => ffi::GRB_INT_PAR_QCPDUAL,
            GRBIntParam::PREMIQCPFORM => ffi::GRB_INT_PAR_PREMIQCPFORM,
            GRBIntParam::PRESPARSIFY => ffi::GRB_INT_PAR_PRESPARSIFY,
            GRBIntParam::PRESOS2ENCODING => ffi::GRB_INT_PAR_PRESOS2ENCODING,
            GRBIntParam::PRESOS1ENCODING => ffi::GRB_INT_PAR_PRESOS1ENCODING,
            GRBIntParam::PRESOLVE => ffi::GRB_INT_PAR_PRESOLVE,
            GRBIntParam::PREQLINEARIZE => ffi::GRB_INT_PAR_PREQLINEARIZE,
            GRBIntParam::PREPASSES => ffi::GRB_INT_PAR_PREPASSES,
            GRBIntParam::PREDUAL => ffi::GRB_INT_PAR_PREDUAL,
            GRBIntParam::PREDEPROW => ffi::GRB_INT_PAR_PREDEPROW,
            GRBIntParam::PRECRUSH => ffi::GRB_INT_PAR_PRECRUSH,
            GRBIntParam::OUTPUTFLAG => ffi::GRB_INT_PAR_OUTPUTFLAG,
            GRBIntParam::NUMERICFOCUS => ffi::GRB_INT_PAR_NUMERICFOCUS,
            GRBIntParam::NONCONVEX => ffi::GRB_INT_PAR_NONCONVEX,
            GRBIntParam::MIQCPMETHOD => ffi::GRB_INT_PAR_MIQCPMETHOD,
            GRBIntParam::LOGTOCONSOLE => ffi::GRB_INT_PAR_LOGTOCONSOLE,
            GRBIntParam::LAZYCONSTRAINTS => ffi::GRB_INT_PAR_LAZYCONSTRAINTS,
            GRBIntParam::JSONSOLDETAIL => ffi::GRB_INT_PAR_JSONSOLDETAIL,
            GRBIntParam::INFUNBDINFO => ffi::GRB_INT_PAR_INFUNBDINFO,
            GRBIntParam::IISMETHOD => ffi::GRB_INT_PAR_IISMETHOD,
            GRBIntParam::DUALREDUCTIONS => ffi::GRB_INT_PAR_DUALREDUCTIONS,
            GRBIntParam::DISTRIBUTEDMIPJOBS => ffi::GRB_INT_PAR_DISTRIBUTEDMIPJOBS,
            GRBIntParam::DISPLAYINTERVAL => ffi::GRB_INT_PAR_DISPLAYINTERVAL,
            GRBIntParam::CONCURRENTJOBS => ffi::GRB_INT_PAR_CONCURRENTJOBS,
            GRBIntParam::CONCURRENTMIP => ffi::GRB_INT_PAR_CONCURRENTMIP,
            GRBIntParam::AGGFILL => ffi::GRB_INT_PAR_AGGFILL,
            GRBIntParam::AGGREGATE => ffi::GRB_INT_PAR_AGGREGATE,
            GRBIntParam::OPTIMALITYTARGET => ffi::GRB_INT_PAR_OPTIMALITYTARGET,
            GRBIntParam::LICENSEID => ffi::GRB_INT_PAR_LICENSEID,
            GRBIntParam::WLSTOKENDURATION => ffi::GRB_INT_PAR_WLSTOKENDURATION,
            GRBIntParam::CSCLIENTLOG => ffi::GRB_INT_PAR_CSCLIENTLOG,
            GRBIntParam::CSBATCHMODE => ffi::GRB_INT_PAR_CSBATCHMODE,
            GRBIntParam::TSPORT => ffi::GRB_INT_PAR_TSPORT,
            GRBIntParam::CSTLSINSECURE => ffi::GRB_INT_PAR_CSTLSINSECURE,
            GRBIntParam::CSIDLETIMEOUT => ffi::GRB_INT_PAR_CSIDLETIMEOUT,
            GRBIntParam::CSPRIORITY => ffi::GRB_INT_PAR_CSPRIORITY,
            GRBIntParam::SERVERTIMEOUT => ffi::GRB_INT_PAR_SERVERTIMEOUT,
            GRBIntParam::GOMORYPASSES => ffi::GRB_INT_PAR_GOMORYPASSES,
            GRBIntParam::CUTPASSES => ffi::GRB_INT_PAR_CUTPASSES,
            GRBIntParam::CUTAGGPASSES => ffi::GRB_INT_PAR_CUTAGGPASSES,
            GRBIntParam::MASTERKNAPSACKCUTS => ffi::GRB_INT_PAR_MASTERKNAPSACKCUTS,
            GRBIntParam::DUALIMPLIEDCUTS => ffi::GRB_INT_PAR_DUALIMPLIEDCUTS,
            GRBIntParam::MIXINGCUTS => ffi::GRB_INT_PAR_MIXINGCUTS,
            GRBIntParam::LIFTPROJECTCUTS => ffi::GRB_INT_PAR_LIFTPROJECTCUTS,
            GRBIntParam::PSDCUTS => ffi::GRB_INT_PAR_PSDCUTS,
            GRBIntParam::BQPCUTS => ffi::GRB_INT_PAR_BQPCUTS,
            GRBIntParam::RELAXLIFTCUTS => ffi::GRB_INT_PAR_RELAXLIFTCUTS,
            GRBIntParam::RLTCUTS => ffi::GRB_INT_PAR_RLTCUTS,
            GRBIntParam::INFPROOFCUTS => ffi::GRB_INT_PAR_INFPROOFCUTS,
            GRBIntParam::SUBMIPCUTS => ffi::GRB_INT_PAR_SUBMIPCUTS,
            GRBIntParam::NETWORKCUTS => ffi::GRB_INT_PAR_NETWORKCUTS,
            GRBIntParam::ZEROHALFCUTS => ffi::GRB_INT_PAR_ZEROHALFCUTS,
            GRBIntParam::MODKCUTS => ffi::GRB_INT_PAR_MODKCUTS,
            GRBIntParam::STRONGCGCUTS => ffi::GRB_INT_PAR_STRONGCGCUTS,
            GRBIntParam::MIRCUTS => ffi::GRB_INT_PAR_MIRCUTS,
            GRBIntParam::MIPSEPCUTS => ffi::GRB_INT_PAR_MIPSEPCUTS,
            GRBIntParam::PROJIMPLIEDCUTS => ffi::GRB_INT_PAR_PROJIMPLIEDCUTS,
            GRBIntParam::IMPLIEDCUTS => ffi::GRB_INT_PAR_IMPLIEDCUTS,
            GRBIntParam::GUBCOVERCUTS => ffi::GRB_INT_PAR_GUBCOVERCUTS,
            GRBIntParam::FLOWPATHCUTS => ffi::GRB_INT_PAR_FLOWPATHCUTS,
            GRBIntParam::FLOWCOVERCUTS => ffi::GRB_INT_PAR_FLOWCOVERCUTS,
            GRBIntParam::COVERCUTS => ffi::GRB_INT_PAR_COVERCUTS,
            GRBIntParam::CLIQUECUTS => ffi::GRB_INT_PAR_CLIQUECUTS,
            GRBIntParam::CUTS => ffi::GRB_INT_PAR_CUTS,
            GRBIntParam::ZEROOBJNODES => ffi::GRB_INT_PAR_ZEROOBJNODES,
            GRBIntParam::SOLUTIONNUMBER => ffi::GRB_INT_PAR_SOLUTIONNUMBER,
            GRBIntParam::VARBRANCH => ffi::GRB_INT_PAR_VARBRANCH,
            GRBIntParam::SYMMETRY => ffi::GRB_INT_PAR_SYMMETRY,
            GRBIntParam::SUBMIPNODES => ffi::GRB_INT_PAR_SUBMIPNODES,
            GRBIntParam::STARTNODELIMIT => ffi::GRB_INT_PAR_STARTNODELIMIT,
            GRBIntParam::RINS => ffi::GRB_INT_PAR_RINS,
            GRBIntParam::PUMPPASSES => ffi::GRB_INT_PAR_PUMPPASSES,
            GRBIntParam::OBBT => ffi::GRB_INT_PAR_OBBT,
            GRBIntParam::NORELHEURSOLUTIONS => ffi::GRB_INT_PAR_NORELHEURSOLUTIONS,
            GRBIntParam::NODEMETHOD => ffi::GRB_INT_PAR_NODEMETHOD,
            GRBIntParam::NLPHEUR => ffi::GRB_INT_PAR_NLPHEUR,
            GRBIntParam::MIPFOCUS => ffi::GRB_INT_PAR_MIPFOCUS,
            GRBIntParam::MINRELNODES => ffi::GRB_INT_PAR_MINRELNODES,
            GRBIntParam::INTEGRALITYFOCUS => ffi::GRB_INT_PAR_INTEGRALITYFOCUS,
            GRBIntParam::FIXVARSININDICATORS => ffi::GRB_INT_PAR_FIXVARSININDICATORS,
            GRBIntParam::DISCONNECTED => ffi::GRB_INT_PAR_DISCONNECTED,
            GRBIntParam::DEGENMOVES => ffi::GRB_INT_PAR_DEGENMOVES,
            GRBIntParam::BRANCHDIR => ffi::GRB_INT_PAR_BRANCHDIR,
            GRBIntParam::PDHGGPU => ffi::GRB_INT_PAR_PDHGGPU,
            GRBIntParam::CROSSOVERBASIS => ffi::GRB_INT_PAR_CROSSOVERBASIS,
            GRBIntParam::CROSSOVER => ffi::GRB_INT_PAR_CROSSOVER,
            GRBIntParam::BARORDER => ffi::GRB_INT_PAR_BARORDER,
            GRBIntParam::BARHOMOGENEOUS => ffi::GRB_INT_PAR_BARHOMOGENEOUS,
            GRBIntParam::BARCORRECTORS => ffi::GRB_INT_PAR_BARCORRECTORS,
            GRBIntParam::NETWORKALG => ffi::GRB_INT_PAR_NETWORKALG,
            GRBIntParam::LPWARMSTART => ffi::GRB_INT_PAR_LPWARMSTART,
            GRBIntParam::SIFTMETHOD => ffi::GRB_INT_PAR_SIFTMETHOD,
            GRBIntParam::SIFTING => ffi::GRB_INT_PAR_SIFTING,
            GRBIntParam::NORMADJUST => ffi::GRB_INT_PAR_NORMADJUST,
            GRBIntParam::QUAD => ffi::GRB_INT_PAR_QUAD,
            GRBIntParam::SIMPLEXPRICING => ffi::GRB_INT_PAR_SIMPLEXPRICING,
            GRBIntParam::SCALEFLAG => ffi::GRB_INT_PAR_SCALEFLAG,
            GRBIntParam::CONCURRENTMETHOD => ffi::GRB_INT_PAR_CONCURRENTMETHOD,
            GRBIntParam::METHOD => ffi::GRB_INT_PAR_METHOD,
            GRBIntParam::NLBARITERLIMIT => ffi::GRB_INT_PAR_NLBARITERLIMIT,
            GRBIntParam::SOLUTIONLIMIT => ffi::GRB_INT_PAR_SOLUTIONLIMIT,
            GRBIntParam::BARITERLIMIT => ffi::GRB_INT_PAR_BARITERLIMIT,
        }
    }
}

#[allow(clippy::upper_case_acronyms)]
#[derive(Clone, Copy)]
pub enum GRBDblParam {
    FUNCMAXVAL,
    FUNCPIECERATIO,
    FUNCPIECEERROR,
    FUNCPIECELENGTH,
    POOLGAPABS,
    POOLGAP,
    TUNETARGETTIME,
    TUNETARGETMIPGAP,
    TUNECLEANUP,
    TUNETIMELIMIT,
    PRESOS2BIGM,
    PRESOS1BIGM,
    FEASRELAXBIGM,
    WLSTOKENREFRESH,
    CSQUEUETIMEOUT,
    STARTWORKLIMIT,
    STARTTIMELIMIT,
    NORELHEURWORK,
    NORELHEURTIME,
    NODEFILESTART,
    IMPROVESTARTNODES,
    IMPROVESTARTWORK,
    IMPROVESTARTTIME,
    IMPROVESTARTGAP,
    HEURISTICS,
    PDHGCONVTOL,
    PDHGABSTOL,
    PDHGRELTOL,
    PDHGITERLIMIT,
    BARQCPCONVTOL,
    BARCONVTOL,
    OBJSCALE,
    PERTURBVALUE,
    NLBARCFEASTOL,
    NLBARDFEASTOL,
    NLBARPFEASTOL,
    PSDTOL,
    OPTIMALITYTOL,
    MIPGAPABS,
    MIPGAP,
    MARKOWITZTOL,
    INTFEASTOL,
    FEASIBILITYTOL,
    BESTBDSTOP,
    BESTOBJSTOP,
    SOFTMEMLIMIT,
    MEMLIMIT,
    WORKLIMIT,
    TIMELIMIT,
    NODELIMIT,
    ITERATIONLIMIT,
    CUTOFF,
}

impl EnvSetter for GRBDblParam {
    type Value = f64;

    fn set(&self, env: *mut ffi::GRBenv, value: Self::Value) -> i32 {
        let attr_name: &CStr = (*self).into();
        unsafe { ffi::GRBsetdblparam(env, attr_name.as_ptr(), value) }
    }
}

impl From<GRBDblParam> for &'static CStr {
    fn from(value: GRBDblParam) -> &'static CStr {
        match value {
            GRBDblParam::FUNCMAXVAL => ffi::GRB_DBL_PAR_FUNCMAXVAL,
            GRBDblParam::FUNCPIECERATIO => ffi::GRB_DBL_PAR_FUNCPIECERATIO,
            GRBDblParam::FUNCPIECEERROR => ffi::GRB_DBL_PAR_FUNCPIECEERROR,
            GRBDblParam::FUNCPIECELENGTH => ffi::GRB_DBL_PAR_FUNCPIECELENGTH,
            GRBDblParam::POOLGAPABS => ffi::GRB_DBL_PAR_POOLGAPABS,
            GRBDblParam::POOLGAP => ffi::GRB_DBL_PAR_POOLGAP,
            GRBDblParam::TUNETARGETTIME => ffi::GRB_DBL_PAR_TUNETARGETTIME,
            GRBDblParam::TUNETARGETMIPGAP => ffi::GRB_DBL_PAR_TUNETARGETMIPGAP,
            GRBDblParam::TUNECLEANUP => ffi::GRB_DBL_PAR_TUNECLEANUP,
            GRBDblParam::TUNETIMELIMIT => ffi::GRB_DBL_PAR_TUNETIMELIMIT,
            GRBDblParam::PRESOS2BIGM => ffi::GRB_DBL_PAR_PRESOS2BIGM,
            GRBDblParam::PRESOS1BIGM => ffi::GRB_DBL_PAR_PRESOS1BIGM,
            GRBDblParam::FEASRELAXBIGM => ffi::GRB_DBL_PAR_FEASRELAXBIGM,
            GRBDblParam::WLSTOKENREFRESH => ffi::GRB_DBL_PAR_WLSTOKENREFRESH,
            GRBDblParam::CSQUEUETIMEOUT => ffi::GRB_DBL_PAR_CSQUEUETIMEOUT,
            GRBDblParam::STARTWORKLIMIT => ffi::GRB_DBL_PAR_STARTWORKLIMIT,
            GRBDblParam::STARTTIMELIMIT => ffi::GRB_DBL_PAR_STARTTIMELIMIT,
            GRBDblParam::NORELHEURWORK => ffi::GRB_DBL_PAR_NORELHEURWORK,
            GRBDblParam::NORELHEURTIME => ffi::GRB_DBL_PAR_NORELHEURTIME,
            GRBDblParam::NODEFILESTART => ffi::GRB_DBL_PAR_NODEFILESTART,
            GRBDblParam::IMPROVESTARTNODES => ffi::GRB_DBL_PAR_IMPROVESTARTNODES,
            GRBDblParam::IMPROVESTARTWORK => ffi::GRB_DBL_PAR_IMPROVESTARTWORK,
            GRBDblParam::IMPROVESTARTTIME => ffi::GRB_DBL_PAR_IMPROVESTARTTIME,
            GRBDblParam::IMPROVESTARTGAP => ffi::GRB_DBL_PAR_IMPROVESTARTGAP,
            GRBDblParam::HEURISTICS => ffi::GRB_DBL_PAR_HEURISTICS,
            GRBDblParam::PDHGCONVTOL => ffi::GRB_DBL_PAR_PDHGCONVTOL,
            GRBDblParam::PDHGABSTOL => ffi::GRB_DBL_PAR_PDHGABSTOL,
            GRBDblParam::PDHGRELTOL => ffi::GRB_DBL_PAR_PDHGRELTOL,
            GRBDblParam::PDHGITERLIMIT => ffi::GRB_DBL_PAR_PDHGITERLIMIT,
            GRBDblParam::BARQCPCONVTOL => ffi::GRB_DBL_PAR_BARQCPCONVTOL,
            GRBDblParam::BARCONVTOL => ffi::GRB_DBL_PAR_BARCONVTOL,
            GRBDblParam::OBJSCALE => ffi::GRB_DBL_PAR_OBJSCALE,
            GRBDblParam::PERTURBVALUE => ffi::GRB_DBL_PAR_PERTURBVALUE,
            GRBDblParam::NLBARCFEASTOL => ffi::GRB_DBL_PAR_NLBARCFEASTOL,
            GRBDblParam::NLBARDFEASTOL => ffi::GRB_DBL_PAR_NLBARDFEASTOL,
            GRBDblParam::NLBARPFEASTOL => ffi::GRB_DBL_PAR_NLBARPFEASTOL,
            GRBDblParam::PSDTOL => ffi::GRB_DBL_PAR_PSDTOL,
            GRBDblParam::OPTIMALITYTOL => ffi::GRB_DBL_PAR_OPTIMALITYTOL,
            GRBDblParam::MIPGAPABS => ffi::GRB_DBL_PAR_MIPGAPABS,
            GRBDblParam::MIPGAP => ffi::GRB_DBL_PAR_MIPGAP,
            GRBDblParam::MARKOWITZTOL => ffi::GRB_DBL_PAR_MARKOWITZTOL,
            GRBDblParam::INTFEASTOL => ffi::GRB_DBL_PAR_INTFEASTOL,
            GRBDblParam::FEASIBILITYTOL => ffi::GRB_DBL_PAR_FEASIBILITYTOL,
            GRBDblParam::BESTBDSTOP => ffi::GRB_DBL_PAR_BESTBDSTOP,
            GRBDblParam::BESTOBJSTOP => ffi::GRB_DBL_PAR_BESTOBJSTOP,
            GRBDblParam::SOFTMEMLIMIT => ffi::GRB_DBL_PAR_SOFTMEMLIMIT,
            GRBDblParam::MEMLIMIT => ffi::GRB_DBL_PAR_MEMLIMIT,
            GRBDblParam::WORKLIMIT => ffi::GRB_DBL_PAR_WORKLIMIT,
            GRBDblParam::TIMELIMIT => ffi::GRB_DBL_PAR_TIMELIMIT,
            GRBDblParam::NODELIMIT => ffi::GRB_DBL_PAR_NODELIMIT,
            GRBDblParam::ITERATIONLIMIT => ffi::GRB_DBL_PAR_ITERATIONLIMIT,
            GRBDblParam::CUTOFF => ffi::GRB_DBL_PAR_CUTOFF,
        }
    }
}

#[allow(clippy::upper_case_acronyms)]
#[derive(Clone, Copy)]
pub enum GRBStrParam {
    JOBID,
    DUMMY,
    RESULTFILE,
    LOGFILE,
    WLSCONFIG,
    WLSPROXY,
    WLSTOKEN,
    WLSSECRET,
    WLSACCESSID,
    CSAPPNAME,
    USERNAME,
    CSAPISECRET,
    CSAPIACCESSID,
    CSAUTHTOKEN,
    CSMANAGER,
    CLOUDHOST,
    CLOUDPOOL,
    CLOUDSECRETKEY,
    CLOUDACCESSID,
    CSGROUP,
    CSROUTER,
    SERVERPASSWORD,
    TOKENSERVER,
    COMPUTESERVER,
    WORKERPASSWORD,
    WORKERPOOL,
    SOLFILES,
    NODEFILEDIR,
}

impl EnvSetter for GRBStrParam {
    type Value = String;

    fn set(&self, env: *mut ffi::GRBenv, value: Self::Value) -> i32 {
        let attr_name: &CStr = (*self).into();
        let value =
            CString::new(value).expect("Failed to convert String to CString in `ModelSetter::set`");
        unsafe { ffi::GRBsetstrparam(env, attr_name.as_ptr(), value.as_ptr()) }
    }
}

impl From<GRBStrParam> for &'static CStr {
    fn from(value: GRBStrParam) -> &'static CStr {
        match value {
            GRBStrParam::JOBID => ffi::GRB_STR_PAR_JOBID,
            GRBStrParam::DUMMY => ffi::GRB_STR_PAR_DUMMY,
            GRBStrParam::RESULTFILE => ffi::GRB_STR_PAR_RESULTFILE,
            GRBStrParam::LOGFILE => ffi::GRB_STR_PAR_LOGFILE,
            GRBStrParam::WLSCONFIG => ffi::GRB_STR_PAR_WLSCONFIG,
            GRBStrParam::WLSPROXY => ffi::GRB_STR_PAR_WLSPROXY,
            GRBStrParam::WLSTOKEN => ffi::GRB_STR_PAR_WLSTOKEN,
            GRBStrParam::WLSSECRET => ffi::GRB_STR_PAR_WLSSECRET,
            GRBStrParam::WLSACCESSID => ffi::GRB_STR_PAR_WLSACCESSID,
            GRBStrParam::CSAPPNAME => ffi::GRB_STR_PAR_CSAPPNAME,
            GRBStrParam::USERNAME => ffi::GRB_STR_PAR_USERNAME,
            GRBStrParam::CSAPISECRET => ffi::GRB_STR_PAR_CSAPISECRET,
            GRBStrParam::CSAPIACCESSID => ffi::GRB_STR_PAR_CSAPIACCESSID,
            GRBStrParam::CSAUTHTOKEN => ffi::GRB_STR_PAR_CSAUTHTOKEN,
            GRBStrParam::CSMANAGER => ffi::GRB_STR_PAR_CSMANAGER,
            GRBStrParam::CLOUDHOST => ffi::GRB_STR_PAR_CLOUDHOST,
            GRBStrParam::CLOUDPOOL => ffi::GRB_STR_PAR_CLOUDPOOL,
            GRBStrParam::CLOUDSECRETKEY => ffi::GRB_STR_PAR_CLOUDSECRETKEY,
            GRBStrParam::CLOUDACCESSID => ffi::GRB_STR_PAR_CLOUDACCESSID,
            GRBStrParam::CSGROUP => ffi::GRB_STR_PAR_CSGROUP,
            GRBStrParam::CSROUTER => ffi::GRB_STR_PAR_CSROUTER,
            GRBStrParam::SERVERPASSWORD => ffi::GRB_STR_PAR_SERVERPASSWORD,
            GRBStrParam::TOKENSERVER => ffi::GRB_STR_PAR_TOKENSERVER,
            GRBStrParam::COMPUTESERVER => ffi::GRB_STR_PAR_COMPUTESERVER,
            GRBStrParam::WORKERPASSWORD => ffi::GRB_STR_PAR_WORKERPASSWORD,
            GRBStrParam::WORKERPOOL => ffi::GRB_STR_PAR_WORKERPOOL,
            GRBStrParam::SOLFILES => ffi::GRB_STR_PAR_SOLFILES,
            GRBStrParam::NODEFILEDIR => ffi::GRB_STR_PAR_NODEFILEDIR,
        }
    }
}
// TODO: Add tests!