libzstd-rs-sys 0.0.1-prerelease.2

a rust implementation of zstd compression and decompression
Documentation
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
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
use core::ffi::{c_int, c_uint, c_ulonglong};
use libc::size_t;

#[cfg(doc)]
use crate::{
    lib::compress::zstd_compress::ZSTD_c_maxBlockSize, ZSTD_CDict, ZSTD_DCtx, ZSTD_DCtx_refDDict,
    ZSTD_DCtx_reset, ZSTD_DCtx_setParameter, ZSTD_DDict, ZSTD_compressBound,
    ZSTD_compress_usingDict, ZSTD_decompress, ZSTD_freeDCtx,
};

pub const ZSTD_FRAMEHEADERSIZE_MAX: core::ffi::c_int = 18;

pub const ZSTD_WINDOWLOG_MAX_32: core::ffi::c_int = 30;
pub const ZSTD_WINDOWLOG_MAX_64: core::ffi::c_int = 31;
pub const ZSTD_WINDOWLOG_MAX: core::ffi::c_int = match size_of::<usize>() {
    4 => ZSTD_WINDOWLOG_MAX_32,
    8 => ZSTD_WINDOWLOG_MAX_64,
    _ => panic!(),
};
/// By default, the streaming decoder will refuse any frame requiring larger than
/// (1<<`ZSTD_WINDOWLOG_LIMIT_DEFAULT`) window size to preserve host's memory from unreasonable
/// requirements. This limit can be overridden using [`ZSTD_DCtx_setParameter`].
///
/// The limit does not apply for one-pass decoders (such as [`ZSTD_decompress`]), since no
/// additional memory is allocated.
pub const ZSTD_WINDOWLOG_LIMIT_DEFAULT: core::ffi::c_int = 27;
pub const ZSTD_WINDOWLOG_ABSOLUTEMIN: core::ffi::c_int = 10;

pub const ZSTD_BLOCKSIZELOG_MAX: c_int = 17;
pub const ZSTD_BLOCKSIZE_MAX: c_int = 1 << ZSTD_BLOCKSIZELOG_MAX;
/// The minimum valid max blocksize. Maximum blocksizes smaller than this make [`ZSTD_compressBound`] inaccurate.
pub const ZSTD_BLOCKSIZE_MAX_MIN: core::ffi::c_int = 1 << 10;
pub const ZSTD_CLEVEL_DEFAULT: c_int = 3;

pub const ZSTD_MAGICNUMBER: c_uint = 0xfd2fb528;
pub const ZSTD_MAGIC_DICTIONARY: c_uint = 0xec30a437;
pub const ZSTD_MAGIC_SKIPPABLE_START: c_uint = 0x184d2a50;
pub const ZSTD_MAGIC_SKIPPABLE_MASK: c_uint = 0xfffffff0;

pub const ZSTD_VERSION_MAJOR: c_uint = 1;
pub const ZSTD_VERSION_MINOR: c_uint = 5;
pub const ZSTD_VERSION_RELEASE: c_uint = 8;
pub const ZSTD_VERSION_NUMBER: c_uint =
    ZSTD_VERSION_MAJOR * 100 * 100 + ZSTD_VERSION_MINOR * 100 + ZSTD_VERSION_RELEASE;

pub const ZSTD_CONTENTSIZE_UNKNOWN: c_ulonglong = (0 as c_ulonglong).wrapping_sub(1);
pub const ZSTD_CONTENTSIZE_ERROR: c_ulonglong = (0 as c_ulonglong).wrapping_sub(2);
pub const ZSTD_SKIPPABLEHEADERSIZE: c_uint = 8;

pub type ZSTD_ErrorCode = core::ffi::c_uint;

pub const ZSTD_error_maxCode: ZSTD_ErrorCode = 120;
pub const ZSTD_error_externalSequences_invalid: ZSTD_ErrorCode = 107;
pub const ZSTD_error_sequenceProducer_failed: ZSTD_ErrorCode = 106;
pub const ZSTD_error_srcBuffer_wrong: ZSTD_ErrorCode = 105;
pub const ZSTD_error_dstBuffer_wrong: ZSTD_ErrorCode = 104;
pub const ZSTD_error_seekableIO: ZSTD_ErrorCode = 102;
pub const ZSTD_error_frameIndex_tooLarge: ZSTD_ErrorCode = 100;
pub const ZSTD_error_noForwardProgress_inputEmpty: ZSTD_ErrorCode = 82;
pub const ZSTD_error_noForwardProgress_destFull: ZSTD_ErrorCode = 80;
pub const ZSTD_error_dstBuffer_null: ZSTD_ErrorCode = 74;
pub const ZSTD_error_srcSize_wrong: ZSTD_ErrorCode = 72;
pub const ZSTD_error_dstSize_tooSmall: ZSTD_ErrorCode = 70;
pub const ZSTD_error_workSpace_tooSmall: ZSTD_ErrorCode = 66;
pub const ZSTD_error_memory_allocation: ZSTD_ErrorCode = 64;
pub const ZSTD_error_init_missing: ZSTD_ErrorCode = 62;
pub const ZSTD_error_stage_wrong: ZSTD_ErrorCode = 60;
pub const ZSTD_error_stabilityCondition_notRespected: ZSTD_ErrorCode = 50;
pub const ZSTD_error_cannotProduce_uncompressedBlock: ZSTD_ErrorCode = 49;
pub const ZSTD_error_maxSymbolValue_tooSmall: ZSTD_ErrorCode = 48;
pub const ZSTD_error_maxSymbolValue_tooLarge: ZSTD_ErrorCode = 46;
pub const ZSTD_error_tableLog_tooLarge: ZSTD_ErrorCode = 44;
pub const ZSTD_error_parameter_outOfBound: ZSTD_ErrorCode = 42;
pub const ZSTD_error_parameter_combination_unsupported: ZSTD_ErrorCode = 41;
pub const ZSTD_error_parameter_unsupported: ZSTD_ErrorCode = 40;
pub const ZSTD_error_dictionaryCreation_failed: ZSTD_ErrorCode = 34;
pub const ZSTD_error_dictionary_wrong: ZSTD_ErrorCode = 32;
pub const ZSTD_error_dictionary_corrupted: ZSTD_ErrorCode = 30;
pub const ZSTD_error_literals_headerWrong: ZSTD_ErrorCode = 24;
pub const ZSTD_error_checksum_wrong: ZSTD_ErrorCode = 22;
pub const ZSTD_error_corruption_detected: ZSTD_ErrorCode = 20;
pub const ZSTD_error_frameParameter_windowTooLarge: ZSTD_ErrorCode = 16;
pub const ZSTD_error_frameParameter_unsupported: ZSTD_ErrorCode = 14;
pub const ZSTD_error_version_unsupported: ZSTD_ErrorCode = 12;
pub const ZSTD_error_prefix_unknown: ZSTD_ErrorCode = 10;
pub const ZSTD_error_GENERIC: ZSTD_ErrorCode = 1;
pub const ZSTD_error_no_error: ZSTD_ErrorCode = 0;

pub type ZSTD_strategy = core::ffi::c_uint;
pub const ZSTD_btultra2: ZSTD_strategy = 9;
pub const ZSTD_btultra: ZSTD_strategy = 8;
pub const ZSTD_btopt: ZSTD_strategy = 7;
pub const ZSTD_btlazy2: ZSTD_strategy = 6;
pub const ZSTD_lazy2: ZSTD_strategy = 5;
pub const ZSTD_lazy: ZSTD_strategy = 4;
pub const ZSTD_greedy: ZSTD_strategy = 3;
pub const ZSTD_dfast: ZSTD_strategy = 2;
pub const ZSTD_fast: ZSTD_strategy = 1;

#[derive(Debug, Copy, Clone, Default)]
#[repr(C)]
pub struct ZSTD_compressionParameters {
    pub windowLog: core::ffi::c_uint,
    pub chainLog: core::ffi::c_uint,
    pub hashLog: core::ffi::c_uint,
    pub searchLog: core::ffi::c_uint,
    pub minMatch: core::ffi::c_uint,
    pub targetLength: core::ffi::c_uint,
    pub strategy: ZSTD_strategy,
}

#[derive(Debug, Copy, Clone, Default)]
#[repr(C)]
pub struct ZSTD_frameParameters {
    pub contentSizeFlag: core::ffi::c_int,
    pub checksumFlag: core::ffi::c_int,
    pub noDictIDFlag: core::ffi::c_int,
}

#[derive(Debug, Copy, Clone, Default)]
#[repr(C)]
pub struct ZSTD_parameters {
    pub cParams: ZSTD_compressionParameters,
    pub fParams: ZSTD_frameParameters,
}

/// This enum specifies the content type of a dictionary, either [`ZSTD_dct_auto`], [`ZSTD_dct_rawContent`], or [`ZSTD_dct_fullDict`].
pub type ZSTD_dictContentType_e = core::ffi::c_uint;
/// Refuses to load a dictionary if it does not respect Zstandard's specification, starting with
/// [`ZSTD_MAGIC_DICTIONARY`]
pub const ZSTD_dct_fullDict: ZSTD_dictContentType_e = 2;
/// Ensures dictionary is always loaded as `rawContent`, even if it starts with [`ZSTD_MAGIC_DICTIONARY`]
pub const ZSTD_dct_rawContent: ZSTD_dictContentType_e = 1;
/// Dictionary is "full" when starting with [`ZSTD_MAGIC_DICTIONARY`], otherwise it is "rawContent"
pub const ZSTD_dct_auto: ZSTD_dictContentType_e = 0;

/// This enum specifies the method used to load a dictionary, either [`ZSTD_dlm_byCopy`] or [`ZSTD_dlm_byRef`].
pub type ZSTD_dictLoadMethod_e = core::ffi::c_uint;
/// Copy dictionary content internally
pub const ZSTD_dlm_byCopy: ZSTD_dictLoadMethod_e = 0;
/// Reference dictionary content -- the dictionary buffer must outlive its users
pub const ZSTD_dlm_byRef: ZSTD_dictLoadMethod_e = 1;

#[derive(Copy, Clone, Default)]
#[repr(C)]
pub struct ZSTD_customMem {
    pub customAlloc: ZSTD_allocFunction,
    pub customFree: ZSTD_freeFunction,
    pub opaque: *mut core::ffi::c_void,
}
pub type ZSTD_freeFunction =
    Option<unsafe extern "C" fn(*mut core::ffi::c_void, *mut core::ffi::c_void) -> ()>;
pub type ZSTD_allocFunction =
    Option<unsafe extern "C" fn(*mut core::ffi::c_void, size_t) -> *mut core::ffi::c_void>;

#[derive(PartialEq)]
#[repr(transparent)]
pub struct ZSTD_format_e(u32);

impl ZSTD_format_e {
    /// zstd frame format, specified in `zstd_compression_format.md` (default)
    pub const ZSTD_f_zstd1: Self = Self(Format::ZSTD_f_zstd1 as u32);

    /// Variant of zstd frame format, without initial 4-bytes magic number.
    ///
    /// Useful to save 4 bytes per generated frame.
    ///
    /// The decoder cannot recognize this format automatically, thus requiring this instruction.
    pub const ZSTD_f_zstd1_magicless: Self = Self(Format::ZSTD_f_zstd1_magicless as u32);
}

impl From<ZSTD_format_e> for u32 {
    fn from(value: ZSTD_format_e) -> Self {
        value.0
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u32)]
pub enum Format {
    ZSTD_f_zstd1 = 0,
    ZSTD_f_zstd1_magicless = 1,
}

impl Format {
    /// This function replaces the `ZSTD_FRAMEHEADERSIZE_MIN` macro.
    ///
    /// Returns the minimum size of the frame header.
    pub const fn frame_header_size_min(self) -> usize {
        match self {
            Format::ZSTD_f_zstd1 => 6,
            Format::ZSTD_f_zstd1_magicless => 2,
        }
    }

    /// This function replaces the `ZSTD_FRAMEHEADERSIZE_PREFIX` macro.
    ///
    /// Returns the minimum input size required to query the frame header size.
    pub const fn starting_input_length(self) -> usize {
        match self {
            Format::ZSTD_f_zstd1 => 5,
            Format::ZSTD_f_zstd1_magicless => 1,
        }
    }
}

impl TryFrom<ZSTD_format_e> for Format {
    type Error = ();

    fn try_from(value: ZSTD_format_e) -> Result<Self, Self::Error> {
        match value {
            ZSTD_format_e::ZSTD_f_zstd1 => Ok(Self::ZSTD_f_zstd1),
            ZSTD_format_e::ZSTD_f_zstd1_magicless => Ok(Self::ZSTD_f_zstd1_magicless),
            _ => Err(()),
        }
    }
}

impl TryFrom<i32> for Format {
    type Error = ();

    fn try_from(value: i32) -> Result<Self, Self::Error> {
        match value {
            0 => Ok(Self::ZSTD_f_zstd1),
            1 => Ok(Self::ZSTD_f_zstd1_magicless),
            _ => Err(()),
        }
    }
}

pub type ZSTD_inBuffer = ZSTD_inBuffer_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct ZSTD_inBuffer_s {
    /// Pointer to start of input buffer
    pub src: *const core::ffi::c_void,
    /// Size of input buffer
    pub size: size_t,
    /// Position where reading stopped. Will be updated. Necessarily `0 <= pos <= size`.
    pub pos: size_t,
}

pub type ZSTD_outBuffer = ZSTD_outBuffer_s;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct ZSTD_outBuffer_s {
    /// Pointer to start of output buffer
    pub dst: *mut core::ffi::c_void,
    /// Size of output buffer
    pub size: size_t,
    /// Position where writing stopped. Will be updated. Necessarily `0 <= pos <= size`.
    pub pos: size_t,
}

pub type ZSTD_bufferMode_e = core::ffi::c_uint;
pub const ZSTD_bm_stable: ZSTD_bufferMode_e = 1;
pub const ZSTD_bm_buffered: ZSTD_bufferMode_e = 0;

#[repr(u32)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum BufferMode {
    Buffered,
    Stable,
}

impl TryFrom<u32> for BufferMode {
    type Error = ();

    fn try_from(value: u32) -> Result<Self, Self::Error> {
        match value {
            0 => Ok(Self::Buffered),
            1 => Ok(Self::Stable),
            _ => Err(()),
        }
    }
}

#[derive(Copy, Clone)]
#[repr(C)]
pub struct ZSTD_frameProgression {
    pub ingested: core::ffi::c_ulonglong,
    pub consumed: core::ffi::c_ulonglong,
    pub produced: core::ffi::c_ulonglong,
    pub flushed: core::ffi::c_ulonglong,
    pub currentJobID: core::ffi::c_uint,
    pub nbActiveWorkers: core::ffi::c_uint,
}

pub mod experimental {
    use crate::lib::zstd::Format;

    pub const fn ZSTD_FRAMEHEADERSIZE_MIN(format: Format) -> usize {
        if let Format::ZSTD_f_zstd1 = format {
            6
        } else {
            2
        }
    }

    pub use crate::lib::common::pool::{
        ZSTD_createThreadPool, ZSTD_freeThreadPool, ZSTD_threadPool,
    };
}

/// The advanced API pushes parameters one by one into an existing `ZSTD_DCtx` decompression
/// context. Parameters are sticky, and remain valid for all following frames using the same
/// context.
///
/// It's possible to reset parameters to default values using [`ZSTD_DCtx_reset`].
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ZSTD_dParameter(u32);

impl ZSTD_dParameter {
    pub const ZSTD_d_experimentalParam1: Self = Self(1000);
    pub const ZSTD_d_experimentalParam2: Self = Self(1001);
    pub const ZSTD_d_experimentalParam3: Self = Self(1002);
    pub const ZSTD_d_experimentalParam4: Self = Self(1003);
    pub const ZSTD_d_experimentalParam5: Self = Self(1004);
    pub const ZSTD_d_experimentalParam6: Self = Self(1005);

    /// Experimental parameter: allowing selection between [`ZSTD_format_e`] input compression formats
    pub const ZSTD_d_format: Self = Self::ZSTD_d_experimentalParam1;

    /// Experimental parameter: tells the decompressor that the [`ZSTD_outBuffer`] will ALWAYS be
    /// the same between calls, except for the modifications that zstd makes to pos (the caller
    /// must not modify pos). This is checked by the decompressor, and decompression will fail if
    /// it ever changes. Therefore the `ZSTD_outBuffer` MUST be large enough to fit the entire
    /// decompressed frame. This will be checked when the frame content size is known. The data in
    /// the `ZSTD_outBuffer` in the range `dst..(dst + pos)` MUST not be modified during
    /// decompression or you will get data corruption.
    ///
    /// When this flag is enabled zstd won't allocate an output buffer, because it can write
    /// directly to the `ZSTD_outBuffer`, but it will still allocate an input buffer large enough
    /// to fit any compressed block. This will also avoid the `memcpy()` from the internal output
    /// buffer to the `ZSTD_outBuffer`. If you need to avoid the input buffer allocation use the
    /// buffer-less streaming API.
    ///
    /// Note: So long as the `ZSTD_outBuffer` always points to valid memory, using this flag is
    /// ALWAYS memory safe, and will never access out-of-bounds memory. However, decompression WILL
    /// fail if you violate the preconditions.
    ///
    /// **Warning:** The data in the `ZSTD_outBuffer` in the range `dst..(dst + pos)` MUST not be
    /// modified during decompression or you will get data corruption. This is because zstd needs
    /// to reference data in the `ZSTD_outBuffer` to regenerate matches. Normally zstd maintains
    /// its own buffer for this purpose, but passing this flag tells zstd to use the user provided
    /// buffer.
    ///
    /// Default is 0 == disabled. Set to 1 to enable.
    pub const ZSTD_d_stableOutBuffer: Self = Self::ZSTD_d_experimentalParam2;

    /// Experimental parameter: tells the decompressor to skip checksum validation during
    /// decompression, regardless of whether checksumming was specified during compression. This
    /// offers some slight performance benefits, and may be useful for debugging.
    ///
    /// Default is 0 == disabled. Set to 1 to enable.
    pub const ZSTD_d_forceIgnoreChecksum: Self = Self::ZSTD_d_experimentalParam3;

    /// Experimental parameter: if enabled and [`ZSTD_DCtx`] is allocated on the heap, then
    /// additional memory will be allocated to store references to multiple [`ZSTD_DDict`]. That
    /// is, multiple calls of [`ZSTD_DCtx_refDDict`] using a given [`ZSTD_DCtx`], rather than
    /// overwriting the previous `DDict` reference, will instead store all references. At
    /// decompression time, the appropriate `dictID` is selected from the set of `DDict`s based on
    /// the `dictID` in the frame.
    ///
    /// **Warning:** Enabling this parameter and calling [`ZSTD_DCtx_refDDict`] will trigger memory
    /// allocation for the hash table. [`ZSTD_freeDCtx`] also frees this memory. Memory is
    /// allocated as per `ZSTD_DCtx::customMem`.
    ///
    /// Although this function allocates memory for the table, the user is still responsible for
    /// memory management of the underlying [`ZSTD_DDict`] themselves.
    ///
    /// Default is 0 == disabled. Set to 1 to enable.
    pub const ZSTD_d_refMultipleDDicts: Self = Self::ZSTD_d_experimentalParam4;

    /// This parameter can be used to disable Huffman assembly at runtime.
    ///
    /// Set to 1 to disable the Huffman assembly implementation. The default value is 0, which
    /// allows zstd to use the Huffman assembly implementation if available.
    pub const ZSTD_d_disableHuffmanAssembly: Self = Self::ZSTD_d_experimentalParam5;

    /// Forces the decompressor to reject blocks whose content size is larger than the configured
    /// `maxBlockSize`. When `maxBlockSize` is larger than the `windowSize`, the `windowSize` is
    /// used instead. This saves memory on the decoder when you know all blocks are small.
    ///
    /// Allowed values are between 1KB and [`ZSTD_BLOCKSIZE_MAX`] (128KB).
    /// The default is [`ZSTD_BLOCKSIZE_MAX`], and setting to 0 will set to the default.
    ///
    /// This option is typically used in conjunction with [`ZSTD_c_maxBlockSize`].
    ///
    /// **Warning:** This causes the decoder to reject otherwise valid frames that have block sizes
    /// larger than the configured `maxBlockSize`.
    pub const ZSTD_d_maxBlockSize: Self = Self::ZSTD_d_experimentalParam6;

    /// Select a size limit (in power of 2) beyond which the streaming API will refuse to allocate
    /// memory buffer in order to protect the host from unreasonable memory requirements.
    ///
    /// This parameter is only useful in streaming mode, since no internal buffer is allocated in
    /// single-pass mode. By default, a decompression context accepts window sizes less than or
    /// equal to (1 << [`ZSTD_WINDOWLOG_LIMIT_DEFAULT`]).
    ///
    /// A value of 0 means "use default maximum `windowLog`".
    pub const ZSTD_d_windowLogMax: Self = Self(100);
}

#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub(crate) enum ForceIgnoreChecksum {
    ValidateChecksum = 0,
    IgnoreChecksum = 1,
}

impl TryFrom<i32> for ForceIgnoreChecksum {
    type Error = ();

    fn try_from(value: i32) -> Result<Self, Self::Error> {
        match value {
            0 => Ok(Self::ValidateChecksum),
            1 => Ok(Self::IgnoreChecksum),
            _ => Err(()),
        }
    }
}

#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ZSTD_cParameter(pub(crate) u32);

impl ZSTD_cParameter {
    pub const ZSTD_c_experimentalParam1: Self = Self(500);
    pub const ZSTD_c_experimentalParam2: Self = Self(10);
    pub const ZSTD_c_experimentalParam3: Self = Self(1000);
    pub const ZSTD_c_experimentalParam4: Self = Self(1001);
    pub const ZSTD_c_experimentalParam5: Self = Self(1002);
    pub const ZSTD_c_experimentalParam7: Self = Self(1004);
    pub const ZSTD_c_experimentalParam8: Self = Self(1005);
    pub const ZSTD_c_experimentalParam9: Self = Self(1006);
    pub const ZSTD_c_experimentalParam10: Self = Self(1007);
    pub const ZSTD_c_experimentalParam11: Self = Self(1008);
    pub const ZSTD_c_experimentalParam12: Self = Self(1009);
    pub const ZSTD_c_experimentalParam13: Self = Self(1010);
    pub const ZSTD_c_experimentalParam14: Self = Self(1011);
    pub const ZSTD_c_experimentalParam15: Self = Self(1012);
    pub const ZSTD_c_experimentalParam16: Self = Self(1013);
    pub const ZSTD_c_experimentalParam17: Self = Self(1014);
    pub const ZSTD_c_experimentalParam18: Self = Self(1015);
    pub const ZSTD_c_experimentalParam19: Self = Self(1016);
    pub const ZSTD_c_experimentalParam20: Self = Self(1017);

    pub const ZSTD_c_rsyncable: Self = Self::ZSTD_c_experimentalParam1;
    pub const ZSTD_c_format: Self = Self::ZSTD_c_experimentalParam2;
    pub const ZSTD_c_forceMaxWindow: Self = Self::ZSTD_c_experimentalParam3;
    pub const ZSTD_c_forceAttachDict: Self = Self::ZSTD_c_experimentalParam4;
    pub const ZSTD_c_literalCompressionMode: Self = Self::ZSTD_c_experimentalParam5;
    pub const ZSTD_c_srcSizeHint: Self = Self::ZSTD_c_experimentalParam7;
    pub const ZSTD_c_enableDedicatedDictSearch: Self = Self::ZSTD_c_experimentalParam8;
    pub const ZSTD_c_stableInBuffer: Self = Self::ZSTD_c_experimentalParam9;
    pub const ZSTD_c_stableOutBuffer: Self = Self::ZSTD_c_experimentalParam10;
    pub const ZSTD_c_blockDelimiters: Self = Self::ZSTD_c_experimentalParam11;
    pub const ZSTD_c_validateSequences: Self = Self::ZSTD_c_experimentalParam12;
    pub const ZSTD_c_blockSplitterLevel: Self = Self::ZSTD_c_experimentalParam20;
    pub const ZSTD_c_splitAfterSequences: Self = Self::ZSTD_c_experimentalParam13;
    pub const ZSTD_c_useRowMatchFinder: Self = Self::ZSTD_c_experimentalParam14;
    pub const ZSTD_c_deterministicRefPrefix: Self = Self::ZSTD_c_experimentalParam15;
    pub const ZSTD_c_prefetchCDictTables: Self = Self::ZSTD_c_experimentalParam16;
    pub const ZSTD_c_enableSeqProducerFallback: Self = Self::ZSTD_c_experimentalParam17;
    pub const ZSTD_c_maxBlockSize: Self = Self::ZSTD_c_experimentalParam18;
    pub const ZSTD_c_repcodeResolution: Self = Self::ZSTD_c_experimentalParam19;
    pub const ZSTD_c_searchForExternalRepcodes: Self = Self::ZSTD_c_experimentalParam19;

    pub const ZSTD_c_compressionLevel: Self = Self(100);
    pub const ZSTD_c_windowLog: Self = Self(101);
    pub const ZSTD_c_hashLog: Self = Self(102);
    pub const ZSTD_c_chainLog: Self = Self(103);
    pub const ZSTD_c_searchLog: Self = Self(104);
    pub const ZSTD_c_minMatch: Self = Self(105);
    pub const ZSTD_c_targetLength: Self = Self(106);
    pub const ZSTD_c_strategy: Self = Self(107);
    pub const ZSTD_c_targetCBlockSize: Self = Self(130);
    pub const ZSTD_c_enableLongDistanceMatching: Self = Self(160);
    pub const ZSTD_c_ldmHashLog: Self = Self(161);
    pub const ZSTD_c_ldmMinMatch: Self = Self(162);
    pub const ZSTD_c_ldmBucketSizeLog: Self = Self(163);
    pub const ZSTD_c_ldmHashRateLog: Self = Self(164);
    pub const ZSTD_c_contentSizeFlag: Self = Self(200);
    pub const ZSTD_c_checksumFlag: Self = Self(201);
    pub const ZSTD_c_dictIDFlag: Self = Self(202);
    pub const ZSTD_c_nbWorkers: Self = Self(400);
    pub const ZSTD_c_jobSize: Self = Self(401);
    pub const ZSTD_c_overlapLog: Self = Self(402);
}

#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ZSTD_ResetDirective(pub(crate) u32);
impl ZSTD_ResetDirective {
    pub const ZSTD_reset_session_only: Self = Self(1);
    pub const ZSTD_reset_parameters: Self = Self(2);
    pub const ZSTD_reset_session_and_parameters: Self = Self(3);
}

/// Note: this enum and the behavior it controls are effectively internal
/// implementation details of the compressor. They are expected to continue
/// to evolve and should be considered only in the context of extremely
/// advanced performance tuning.
///
/// Zstd currently supports the use of a [`ZSTD_CDict`] in three ways:
///
/// - The contents of the `CDict` can be copied into the working context. This
///   means that the compression can search both the dictionary and input
///   while operating on a single set of internal tables. This makes
///   the compression faster per byte of input. However, the initial copy of
///   the `CDict`'s tables incurs a fixed cost at the beginning of the
///   compression. For small compressions (< 8 KB), that copy can dominate
///   the cost of the compression.
///
/// - The `CDict`'s tables can be used in-place. In this model, compression is
///   slower per input byte, because the compressor has to search two sets of
///   tables. However, this model incurs no start-up cost (as long as the
///   working context's tables can be reused). For small inputs, this can be
///   faster than copying the `CDict`'s tables.
///
/// - The `CDict`'s tables are not used at all, and instead we use the working
///   context alone to reload the dictionary and use params based on the source
///   size. See `ZSTD_compress_insertDictionary` and [`ZSTD_compress_usingDict`].
///   This method is effective when the dictionary sizes are very small relative
///   to the input size, and the input size is fairly large to begin with.
///
/// Zstd has a simple internal heuristic that selects which strategy to use
/// at the beginning of a compression. However, if experimentation shows that
/// Zstd is making poor choices, it is possible to override that choice with
/// this enum.
#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct ZSTD_dictAttachPref_e(pub(crate) u32);
impl ZSTD_dictAttachPref_e {
    /// Use the default heuristic
    pub const ZSTD_dictDefaultAttach: Self = Self(0);
    /// Never copy the dictionary
    pub const ZSTD_dictForceAttach: Self = Self(1);
    /// Always copy the dictionary
    pub const ZSTD_dictForceCopy: Self = Self(2);
    /// Always reload the dictionary
    pub const ZSTD_dictForceLoad: Self = Self(3);
}

impl TryFrom<i32> for ZSTD_dictAttachPref_e {
    type Error = ();

    fn try_from(value: i32) -> Result<Self, Self::Error> {
        match value {
            0 => Ok(Self::ZSTD_dictDefaultAttach),
            1 => Ok(Self::ZSTD_dictForceAttach),
            2 => Ok(Self::ZSTD_dictForceCopy),
            3 => Ok(Self::ZSTD_dictForceLoad),
            _ => Err(()),
        }
    }
}

/// Note: this enum controls features which are conditionally beneficial.
///
/// Zstd can take a decision on whether or not to enable the feature (`ZSTD_ps_auto`),
/// or set the switch to `ZSTD_ps_enable` or `ZSTD_ps_disable` force enable/disable the feature.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ZSTD_ParamSwitch_e {
    /// Let the library automatically determine whether the feature shall be enabled
    ZSTD_ps_auto = 0,
    /// Force-enable the feature
    ZSTD_ps_enable = 1,
    /// Force-disable the feature
    ZSTD_ps_disable = 2,
}

impl ZSTD_ParamSwitch_e {
    pub fn to_i32(self) -> i32 {
        self as i32
    }
}

impl TryFrom<i32> for ZSTD_ParamSwitch_e {
    type Error = ();

    fn try_from(value: i32) -> Result<Self, Self::Error> {
        match value {
            0 => Ok(Self::ZSTD_ps_auto),
            1 => Ok(Self::ZSTD_ps_enable),
            2 => Ok(Self::ZSTD_ps_disable),
            _ => Err(()),
        }
    }
}