xrpl_hooks/api/
mod.rs

1use crate::_c;
2
3mod control;
4mod etxn;
5mod float;
6mod ledger;
7mod otxn;
8mod slot;
9mod state;
10mod sto;
11mod trace;
12mod util;
13
14pub use control::*;
15pub use etxn::*;
16pub use float::*;
17pub use ledger::*;
18pub use otxn::*;
19pub use slot::*;
20pub use state::*;
21pub use sto::*;
22pub use trace::*;
23pub use util::*;
24
25/// Flags canonical
26pub const TF_CANONICAL: u32 = _c::tfCANONICAL;
27
28/// Account id buffer lenght
29pub const ACC_ID_LEN: usize = 20;
30/// Currency code buffer lenght
31pub const CURRENCY_CODE_SIZE: usize = 20;
32/// Ledger hash buffer lenght
33pub const LEDGER_HASH_LEN: usize = 32;
34/// Keylet buffer lenght
35pub const KEYLET_LEN: usize = 34;
36/// State key buffer lenght
37pub const STATE_KEY_LEN: usize = 32;
38/// Nonce buffer lenght
39pub const NONCE_LEN: usize = 32;
40/// Hash buffer lenght
41pub const HASH_LEN: usize = 32;
42/// Amount buffer lenght
43pub const AMOUNT_LEN: usize = 48;
44/// Payment simple transaction buffer lenght
45pub const PREPARE_PAYMENT_SIMPLE_SIZE: usize = _c::PREPARE_PAYMENT_SIMPLE_SIZE as _;
46/// Emit details buffer lenght
47pub const EMIT_DETAILS_SIZE: usize = 105;
48
49/// Buffer of the specified size
50pub type Buffer<const T: usize> = [u8; T];
51
52/// Account id buffer
53pub type AccountId = Buffer<ACC_ID_LEN>;
54/// Hash buffer
55pub type Hash = Buffer<HASH_LEN>;
56/// Keylet buffer
57pub type Keylet = Buffer<KEYLET_LEN>;
58/// State key buffer
59pub type StateKey = Buffer<STATE_KEY_LEN>;
60/// Nonce buffer
61pub type Nonce = Buffer<NONCE_LEN>;
62/// Amount buffer
63pub type Amount = Buffer<AMOUNT_LEN>;
64/// Simple payment transaction buffer
65pub type TxnPaymentSimple = Buffer<PREPARE_PAYMENT_SIMPLE_SIZE>;
66/// Emit details buffer
67pub type EmitDetails = Buffer<EMIT_DETAILS_SIZE>;
68/// Currency code buffer
69pub type CurrencyCode = Buffer<CURRENCY_CODE_SIZE>;
70
71/// Transaction type
72#[allow(missing_docs)]
73#[derive(Clone, Copy)]
74#[repr(u32)]
75pub enum TxnType {
76    Payment = _c::ttPAYMENT,
77    EscrowCreate = 1,
78    EscrowFinish = 2,
79    AccountSet = 3,
80    EscrowCancel = 4,
81    RegularKeySet = 5,
82    OfferCreate = 7,
83    OfferCancel = 8,
84    TicketCreate = 10,
85    TicketCancel = 11,
86    SignerListSet = 12,
87    PaychanCreate = 13,
88    PaychanFund = 14,
89    PaychanClaim = 15,
90    CheckCreate = 16,
91    CheckCash = 17,
92    CheckCancel = 18,
93    DepositPreauth = 19,
94    TrustSet = 20,
95    AccountDelete = 21,
96    HookSet = 22,
97    Amendment = 100,
98    Fee = 101,
99    UnlModify = 102,
100}
101
102/// Account type
103#[allow(missing_docs)]
104#[derive(Clone, Copy)]
105#[repr(u32)]
106pub enum AccountType {
107    Account = _c::atACCOUNT,
108    Owner = _c::atOWNER,
109    Destination = _c::atDESTINATION,
110    Issuer = _c::atISSUER,
111    Authorize = _c::atAUTHORIZE,
112    Unauthorize = _c::atUNAUTHORIZE,
113    Target = _c::atTARGET,
114    RegularKey = _c::atREGULARKEY,
115    PseudoCallback = _c::atPSEUDOCALLBACK,
116}
117
118/// Amount type
119#[allow(missing_docs)]
120#[derive(Clone, Copy)]
121#[repr(u32)]
122pub enum AmountType {
123    Amount = _c::amAMOUNT,
124    Balance = _c::amBALANCE,
125    LimitAmount = _c::amLIMITAMOUNT,
126    TakerPays = _c::amTAKERPAYS,
127    TakerGets = _c::amTAKERGETS,
128    LowLimit = _c::amLOWLIMIT,
129    HighLimit = _c::amHIGHLIMIT,
130    Fee = _c::amFEE,
131    SendMax = _c::amSENDMAX,
132    DeliverMin = _c::amDELIVERMIN,
133    MinimumOffer = _c::amMINIMUMOFFER,
134    RippleEscrow = _c::amRIPPLEESCROW,
135    DeliveredAmount = _c::amDELIVEREDAMOUNT,
136}
137
138/// Keylet type
139#[allow(missing_docs)]
140#[derive(Clone, Copy)]
141pub enum KeyletType<'a> {
142    Hook(&'a [u8]),
143    HookState(&'a [u8], &'a [u8]),
144    Account(&'a [u8]),
145    Amendments,
146    Child(&'a [u8]),
147    Skip(Option<(u32, u32)>),
148    Fees,
149    NegativeUnl,
150    Line(&'a [u8], &'a [u8], &'a [u8]),
151    Offer(&'a [u8], u32),
152    Quality(&'a [u8], u32, u32),
153    EmittedDir,
154    Signers(&'a [u8]),
155    Check(&'a [u8], u32),
156    DepositPreauth(&'a [u8], &'a [u8]),
157    Unchecked(&'a [u8]),
158    OwnerDir(&'a [u8]),
159    Page(&'a [u8], u32, u32),
160    Escrow(&'a [u8], u32),
161    Paychan(&'a [u8], &'a [u8], u32),
162    Emitted(&'a [u8]),
163}
164
165/// Field or amount type
166///
167/// Used as return of [slot_type] function
168#[derive(Clone, Copy)]
169pub enum FieldOrXrpAmount {
170    /// Field ID
171    Field(FieldId),
172    /// STI_AMOUNT type contains a native (XRP) amount
173    XrpAmount,
174    /// STI_AMOUNT type contains non-XRP amount
175    NonXrpAmount,
176}
177
178/// Flags for [slot_type]
179#[derive(Clone, Copy)]
180pub enum SlotTypeFlags {
181    /// Field
182    Field,
183    /// STI_AMOUNT type contains a native (XRP) amount
184    XrpAmount,
185}
186
187/// Field type
188#[allow(missing_docs)]
189#[derive(Clone, Copy)]
190#[repr(u32)]
191pub enum FieldId {
192    Generic = _c::sfGeneric,
193    LedgerEntry = _c::sfLedgerEntry,
194    Transaction = _c::sfTransaction,
195    Validation = _c::sfValidation,
196    Metadata = _c::sfMetadata,
197    Hash = _c::sfHash,
198    Index = _c::sfIndex,
199    CloseResolution = _c::sfCloseResolution,
200    Method = _c::sfMethod,
201    TransactionResult = _c::sfTransactionResult,
202    TickSize = _c::sfTickSize,
203    UNLModifyDisabling = _c::sfUNLModifyDisabling,
204    LedgerEntryType = _c::sfLedgerEntryType,
205    TransactionType = _c::sfTransactionType,
206    SignerWeight = _c::sfSignerWeight,
207    Version = _c::sfVersion,
208    Flags = _c::sfFlags,
209    SourceTag = _c::sfSourceTag,
210    Sequence = _c::sfSequence,
211    PreviousTxnLgrSeq = _c::sfPreviousTxnLgrSeq,
212    LedgerSequence = _c::sfLedgerSequence,
213    CloseTime = _c::sfCloseTime,
214    ParentCloseTime = _c::sfParentCloseTime,
215    SigningTime = _c::sfSigningTime,
216    Expiration = _c::sfExpiration,
217    TransferRate = _c::sfTransferRate,
218    WalletSize = _c::sfWalletSize,
219    OwnerCount = _c::sfOwnerCount,
220    DestinationTag = _c::sfDestinationTag,
221    HighQualityIn = _c::sfHighQualityIn,
222    HighQualityOut = _c::sfHighQualityOut,
223    LowQualityIn = _c::sfLowQualityIn,
224    LowQualityOut = _c::sfLowQualityOut,
225    QualityIn = _c::sfQualityIn,
226    QualityOut = _c::sfQualityOut,
227    StampEscrow = _c::sfStampEscrow,
228    BondAmount = _c::sfBondAmount,
229    LoadFee = _c::sfLoadFee,
230    OfferSequence = _c::sfOfferSequence,
231    FirstLedgerSequence = _c::sfFirstLedgerSequence,
232    LastLedgerSequence = _c::sfLastLedgerSequence,
233    TransactionIndex = _c::sfTransactionIndex,
234    OperationLimit = _c::sfOperationLimit,
235    ReferenceFeeUnits = _c::sfReferenceFeeUnits,
236    ReserveBase = _c::sfReserveBase,
237    ReserveIncrement = _c::sfReserveIncrement,
238    SetFlag = _c::sfSetFlag,
239    ClearFlag = _c::sfClearFlag,
240    SignerQuorum = _c::sfSignerQuorum,
241    CancelAfter = _c::sfCancelAfter,
242    FinishAfter = _c::sfFinishAfter,
243    SignerListID = _c::sfSignerListID,
244    SettleDelay = _c::sfSettleDelay,
245    HookStateCount = _c::sfHookStateCount,
246    HookReserveCount = _c::sfHookReserveCount,
247    HookDataMaxSize = _c::sfHookDataMaxSize,
248    EmitGeneration = _c::sfEmitGeneration,
249    IndexNext = _c::sfIndexNext,
250    IndexPrevious = _c::sfIndexPrevious,
251    BookNode = _c::sfBookNode,
252    OwnerNode = _c::sfOwnerNode,
253    BaseFee = _c::sfBaseFee,
254    ExchangeRate = _c::sfExchangeRate,
255    LowNode = _c::sfLowNode,
256    HighNode = _c::sfHighNode,
257    DestinationNode = _c::sfDestinationNode,
258    Cookie = _c::sfCookie,
259    ServerVersion = _c::sfServerVersion,
260    EmitBurden = _c::sfEmitBurden,
261    HookOn = _c::sfHookOn,
262    EmailHash = _c::sfEmailHash,
263    TakerPaysCurrency = _c::sfTakerPaysCurrency,
264    TakerPaysIssuer = _c::sfTakerPaysIssuer,
265    TakerGetsCurrency = _c::sfTakerGetsCurrency,
266    TakerGetsIssuer = _c::sfTakerGetsIssuer,
267    LedgerHash = _c::sfLedgerHash,
268    ParentHash = _c::sfParentHash,
269    TransactionHash = _c::sfTransactionHash,
270    AccountHash = _c::sfAccountHash,
271    PreviousTxnID = _c::sfPreviousTxnID,
272    LedgerIndex = _c::sfLedgerIndex,
273    WalletLocator = _c::sfWalletLocator,
274    RootIndex = _c::sfRootIndex,
275    AccountTxnID = _c::sfAccountTxnID,
276    EmitParentTxnID = _c::sfEmitParentTxnID,
277    EmitNonce = _c::sfEmitNonce,
278    BookDirectory = _c::sfBookDirectory,
279    InvoiceID = _c::sfInvoiceID,
280    Nickname = _c::sfNickname,
281    Amendment = _c::sfAmendment,
282    TicketID = _c::sfTicketID,
283    Digest = _c::sfDigest,
284    PayChannel = _c::sfPayChannel,
285    ConsensusHash = _c::sfConsensusHash,
286    CheckID = _c::sfCheckID,
287    ValidatedHash = _c::sfValidatedHash,
288    Amount = _c::sfAmount,
289    Balance = _c::sfBalance,
290    LimitAmount = _c::sfLimitAmount,
291    TakerPays = _c::sfTakerPays,
292    TakerGets = _c::sfTakerGets,
293    LowLimit = _c::sfLowLimit,
294    HighLimit = _c::sfHighLimit,
295    Fee = _c::sfFee,
296    SendMax = _c::sfSendMax,
297    DeliverMin = _c::sfDeliverMin,
298    MinimumOffer = _c::sfMinimumOffer,
299    RippleEscrow = _c::sfRippleEscrow,
300    DeliveredAmount = _c::sfDeliveredAmount,
301    PublicKey = _c::sfPublicKey,
302    MessageKey = _c::sfMessageKey,
303    SigningPubKey = _c::sfSigningPubKey,
304    TxnSignature = _c::sfTxnSignature,
305    Signature = _c::sfSignature,
306    Domain = _c::sfDomain,
307    FundCode = _c::sfFundCode,
308    RemoveCode = _c::sfRemoveCode,
309    ExpireCode = _c::sfExpireCode,
310    CreateCode = _c::sfCreateCode,
311    MemoType = _c::sfMemoType,
312    MemoData = _c::sfMemoData,
313    MemoFormat = _c::sfMemoFormat,
314    Fulfillment = _c::sfFulfillment,
315    Condition = _c::sfCondition,
316    MasterSignature = _c::sfMasterSignature,
317    UNLModifyValidator = _c::sfUNLModifyValidator,
318    NegativeUNLToDisable = _c::sfNegativeUNLToDisable,
319    NegativeUNLToReEnable = _c::sfNegativeUNLToReEnable,
320    HookData = _c::sfHookData,
321    Account = _c::sfAccount,
322    Owner = _c::sfOwner,
323    Destination = _c::sfDestination,
324    Issuer = _c::sfIssuer,
325    Authorize = _c::sfAuthorize,
326    Unauthorize = _c::sfUnauthorize,
327    Target = _c::sfTarget,
328    RegularKey = _c::sfRegularKey,
329    Paths = _c::sfPaths,
330    Indexes = _c::sfIndexes,
331    Hashes = _c::sfHashes,
332    Amendments = _c::sfAmendments,
333    TransactionMetaData = _c::sfTransactionMetaData,
334    CreatedNode = _c::sfCreatedNode,
335    DeletedNode = _c::sfDeletedNode,
336    ModifiedNode = _c::sfModifiedNode,
337    PreviousFields = _c::sfPreviousFields,
338    FinalFields = _c::sfFinalFields,
339    NewFields = _c::sfNewFields,
340    TemplateEntry = _c::sfTemplateEntry,
341    Memo = _c::sfMemo,
342    SignerEntry = _c::sfSignerEntry,
343    EmitDetails = _c::sfEmitDetails,
344    Signer = _c::sfSigner,
345    Majority = _c::sfMajority,
346    NegativeUNLEntry = _c::sfNegativeUNLEntry,
347    SigningAccounts = _c::sfSigningAccounts,
348    Signers = _c::sfSigners,
349    SignerEntries = _c::sfSignerEntries,
350    Template = _c::sfTemplate,
351    Necessary = _c::sfNecessary,
352    Sufficient = _c::sfSufficient,
353    AffectedNodes = _c::sfAffectedNodes,
354    Memos = _c::sfMemos,
355    Majorities = _c::sfMajorities,
356    NegativeUNL = _c::sfNegativeUNL,
357}
358
359/// Data representation
360#[derive(Clone, Copy)]
361pub enum DataRepr {
362    /// As UTF-8
363    AsUTF8 = 0,
364    /// As hexadecimal
365    AsHex = 1,
366}
367
368/// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]).
369//
370/// This is simple version of Result type
371/// to comply XRPL Hooks Webassembly restrictions
372#[must_use]
373pub enum Result<T> {
374    /// Contains the success value
375    Ok(T),
376    /// Contains the error value
377    Err(Error),
378}
379
380pub use self::Result::*;
381
382#[must_use]
383impl<T> Result<T> {
384    /// Returns the contained [`Ok`] value, consuming the `self` value.
385    ///
386    /// # Rollbacks
387    ///
388    /// Rollbacks if the value is an [`Err`], with a rollback message and error code.
389    #[inline(always)]
390    pub fn expect(self, msg: &[u8]) -> T {
391        match self {
392            Err(e) => rollback(msg, e.code() as _),
393            Ok(val) => val,
394        }
395    }
396
397    /// Returns the contained [`Ok`] value, consuming the `self` value.
398    ///
399    /// Because this function may rollback, its use is generally discouraged.
400    /// Instead, prefer to use pattern matching and handle the [`Err`]
401    /// case explicitly.
402    ///
403    /// # Rollbacks
404    ///
405    /// Rollbacks if the value is an [`Err`], with a "error" and error code provided by the
406    /// [`Err`]'s value.
407    #[inline(always)]
408    pub fn unwrap(self) -> T {
409        match self {
410            Err(e) => rollback(b"error", e.code() as _),
411            Ok(val) => val,
412        }
413    }
414
415    /// Returns the contained [`Ok`] value, consuming the `self` value,
416    /// without checking that the value is not an [`Err`].
417    ///
418    /// # Safety
419    ///
420    /// Calling this method on an [`Err`] is *[undefined behavior]*.
421    ///
422    /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
423    #[inline(always)]
424    pub unsafe fn unwrap_unchecked(self) -> T {
425        match self {
426            Ok(val) => val,
427            // SAFETY: the safety contract must be upheld by the caller.
428            Err(_) => core::hint::unreachable_unchecked(),
429        }
430    }
431
432    /// Returns `true` if the result is [`Ok`].
433    #[must_use]
434    #[inline(always)]
435    pub const fn is_ok(&self) -> bool {
436        matches!(*self, Ok(_))
437    }
438
439    /// Returns `true` if the result is [`Err`].
440    #[must_use]
441    #[inline(always)]
442    pub const fn is_err(&self) -> bool {
443        !self.is_ok()
444    }
445}
446
447/// Possible errors returned by Hook APIs.
448///
449/// Errors are global across all Hook APIs.
450#[derive(Clone, Copy)]
451#[repr(i32)]
452pub enum Error {
453    /// A pointer or buffer length provided as a parameter described memory outside of the Hook's allowed memory region.
454    OutOfBounds = _c::OUT_OF_BOUNDS,
455    /// Reserved for internal invariant trips, generally unrelated to inputs.
456    /// These should be reported with an issue.
457    InternalError = _c::INTERNAL_ERROR,
458    /// Attempted to set a parameter or value larger than the allowed space .
459    TooBig = _c::TOO_BIG,
460    /// The API was unable to produce output to the write_ptr because the specified write_len was too small
461    TooSmall = _c::TOO_SMALL,
462    /// The requested object or item wasn't found
463    DoesntExist = _c::DOESNT_EXIST,
464    /// The Hook attempted to allocate an item into a slot, but there were no slots free.
465    /// To avoid ensure re-use of existing slots. The maximum number of slots is 255.
466    NoFreeSlots = _c::NO_FREE_SLOTS,
467    /// One or more of the parameters to the API were invalid according to the individual API's specification.
468    InvalidArgument = _c::INVALID_ARGUMENT,
469    /// Some APIs allow for a once-per-execution parameter to be set.
470    /// A second attempt to set a once-per-execution parameter results in this error.
471    AlreadySet = _c::ALREADY_SET,
472    /// An API required the Hook to do something before the API is allowed to be called.
473    /// Check the API's documentation.
474    PrerequisiteNotMet = _c::PREREQUISITE_NOT_MET,
475    /// During fee calculation if an absurdly large fee is calculated this error is returned.
476    FeeTooLarge = _c::FEE_TOO_LARGE,
477    /// An attempt to emit() a TXN was unsccessful for any of a number of reasons.
478    /// Check the trace log of the rippled to which you are submitting the originating TXN.
479    EmissionFailure = _c::EMISSION_FAILURE,
480    /// A Hook may only use up to 256 calls to nonce() per execution.
481    /// Further calls result in this error code.
482    TooManyNonces = _c::TOO_MANY_NONCES,
483    /// A Hook must declare ahead of time how many TXN it intends to emit().
484    /// If it emits fewer than this many, this is allowed.
485    /// If it emits more than this many this error is returned.
486    TooManyEmittedTxn = _c::TOO_MANY_EMITTED_TXN,
487    /// While Hooks is/was in development an API may return this if some or all of that API is planned but not yet implemented.
488    NotImplemented = _c::NOT_IMPLEMENTED,
489    /// An API which accepts a 20 byte Account ID may return this if, in its opinion, the Account ID was not valid for any reason.
490    InvalidAccount = _c::INVALID_ACCOUNT,
491    /// All loops inside a Hook must declare at the top of the loop, as the first non trivial instruction,
492    /// before any branch instruction, the promised maximum number of iterations of the loop.
493    /// If this promise is violated the hook terminates immediately with this error code.
494    GuardViolation = _c::GUARD_VIOLATION,
495    /// The requested serialized field could not be found in the specified object.
496    InvalidField = _c::INVALID_FIELD,
497    /// While parsing serialized content an error was encountered (typically indicating an invalidly serialized object).
498    ParseError = _c::PARSE_ERROR,
499    /// Used internally to communicate a rollback event.
500    RcRollback = _c::RC_ROLLBACK,
501    /// Used internally to communicate an accept event.
502    RcAccept = _c::RC_ACCEPT,
503    /// Specified keylet could not be found, or keylet is invalid
504    NoSuchKeylet = _c::NO_SUCH_KEYLET,
505    /// API was asked to assume object under analysis is an STArray but it was not.
506    NotAnArray = -22,
507    /// API was asked to assume object under analysis is an STObject but it was not.
508    NotAnObject = -23,
509    /// A floating point operation resulted in Not-A-Number or API call attempted to specify an XFL floating point number outside of the expressible range of XFL.
510    InvalidFloat = _c::INVALID_FLOAT,
511    /// API call would result in a division by zero, so API ended early.
512    DivisionByZero = -25,
513    /// When attempting to create an XFL the mantissa must be 16 decimal digits.
514    ManitssaOversized = -26,
515    /// When attempting to create an XFL the mantissa must be 16 decimal digits.
516    MantissaUndersized = -27,
517    /// When attempting to create an XFL the exponent must not exceed 80.
518    ExponentOversized = -28,
519    /// When attempting to create an XFL the exponent must not be less than -96.
520    ExponentUndersized = -29,
521    /// A floating point operation done on an XFL resulted in a value larger than XFL format is able to represent.
522    Overflow = -30,
523    /// An API assumed an STAmount was an IOU when in fact it was XRP.
524    NotIouAmount = -31,
525    /// An API assumed an STObject was an STAmount when in fact it was not.
526    NotAnAmount = -32,
527    /// An API would have returned a negative integer except that negative integers are reserved for error codes (i.e. what you are reading.)
528    CantReturnNegative = -33,
529}
530
531impl Error {
532    #[inline(always)]
533    fn from_code(code: i32) -> Self {
534        unsafe { core::mem::transmute(code) }
535    }
536
537    /// Error code
538    #[inline(always)]
539    pub fn code(self) -> i32 {
540        self as _
541    }
542}
543
544type Api1ArgsU32 = unsafe extern "C" fn(u32) -> i64;
545type Api2ArgsU32 = unsafe extern "C" fn(u32, u32) -> i64;
546type Api3ArgsU32 = unsafe extern "C" fn(u32, u32, u32) -> i64;
547type Api4ArgsU32 = unsafe extern "C" fn(u32, u32, u32, u32) -> i64;
548type Api6ArgsU32 = unsafe extern "C" fn(u32, u32, u32, u32, u32, u32) -> i64;
549
550type BufWriter = Api2ArgsU32;
551type BufReader = Api2ArgsU32;
552type Buf2Reader = Api4ArgsU32;
553type BufWriterReader = Api4ArgsU32;
554type Buf3Reader = Api6ArgsU32;
555type BufWriter1Arg = Api3ArgsU32;
556
557#[inline(always)]
558fn api_1arg_call(arg: u32, fun: Api1ArgsU32) -> Result<u64> {
559    let res = unsafe { fun(arg) };
560
561    result_u64(res)
562}
563
564#[inline(always)]
565fn api_3arg_call(arg_1: u32, arg_2: u32, arg_3: u32, fun: Api3ArgsU32) -> Result<u64> {
566    let res = unsafe { fun(arg_1, arg_2, arg_3) };
567
568    result_u64(res)
569}
570
571#[inline(always)]
572fn buf_write(buf_write: &mut [u8], fun: BufWriter) -> Result<u64> {
573    let res = unsafe { fun(buf_write.as_mut_ptr() as u32, buf_write.len() as u32) };
574
575    result_u64(res)
576}
577
578#[inline(always)]
579fn buf_write_1arg(buf_write: &mut [u8], arg: u32, fun: BufWriter1Arg) -> Result<u64> {
580    let res = unsafe { fun(buf_write.as_mut_ptr() as u32, buf_write.len() as u32, arg) };
581
582    result_u64(res)
583}
584
585#[inline(always)]
586fn buf_read(buf: &[u8], fun: BufReader) -> Result<u64> {
587    let res = unsafe { fun(buf.as_ptr() as u32, buf.len() as u32) };
588
589    result_u64(res)
590}
591
592#[inline(always)]
593fn buf_2read(buf_1: &[u8], buf_2: &[u8], fun: Buf2Reader) -> Result<u64> {
594    let res = unsafe {
595        fun(
596            buf_1.as_ptr() as u32,
597            buf_1.len() as u32,
598            buf_2.as_ptr() as u32,
599            buf_2.len() as u32,
600        )
601    };
602
603    result_u64(res)
604}
605
606#[inline(always)]
607fn buf_write_read(buf_write: &mut [u8], buf_read: &[u8], fun: BufWriterReader) -> Result<u64> {
608    let res = unsafe {
609        fun(
610            buf_write.as_mut_ptr() as u32,
611            buf_write.len() as u32,
612            buf_read.as_ptr() as u32,
613            buf_read.len() as u32,
614        )
615    };
616
617    result_u64(res)
618}
619
620#[inline(always)]
621fn buf_3_read(
622    buf_read_1: &[u8],
623    buf_read_2: &[u8],
624    buf_read_3: &[u8],
625    fun: Buf3Reader,
626) -> Result<u64> {
627    let res = unsafe {
628        fun(
629            buf_read_1.as_ptr() as u32,
630            buf_read_1.len() as u32,
631            buf_read_2.as_ptr() as u32,
632            buf_read_2.len() as u32,
633            buf_read_3.as_ptr() as u32,
634            buf_read_3.len() as u32,
635        )
636    };
637
638    result_u64(res)
639}
640
641#[inline(always)]
642fn range_from_location(location: i64) -> core::ops::Range<usize> {
643    let offset: i32 = (location >> 32) as _;
644    let lenght: i32 = (location & 0xFFFFFFFF) as _;
645
646    core::ops::Range {
647        start: offset as _,
648        end: (offset + lenght) as _,
649    }
650}
651
652#[inline(always)]
653fn all_zeroes(buf_write: &mut [u8], keylet_type_c: u32) -> Result<u64> {
654    let res = unsafe {
655        _c::util_keylet(
656            buf_write.as_mut_ptr() as _,
657            buf_write.len() as _,
658            keylet_type_c,
659            0,
660            0,
661            0,
662            0,
663            0,
664            0,
665        )
666    };
667
668    result_u64(res)
669}
670
671#[inline(always)]
672fn buf_read_and_zeroes(buf_write: &mut [u8], buf_read: &[u8], keylet_type_c: u32) -> Result<u64> {
673    let res = unsafe {
674        _c::util_keylet(
675            buf_write.as_mut_ptr() as _,
676            buf_write.len() as _,
677            keylet_type_c,
678            buf_read.as_ptr() as _,
679            buf_read.len() as _,
680            0,
681            0,
682            0,
683            0,
684        )
685    };
686
687    result_u64(res)
688}
689
690#[inline(always)]
691fn buf_read_and_1_arg(
692    buf_write: &mut [u8],
693    buf_read: &[u8],
694    arg: u32,
695    keylet_type_c: u32,
696) -> Result<u64> {
697    let res = unsafe {
698        _c::util_keylet(
699            buf_write.as_mut_ptr() as _,
700            buf_write.len() as _,
701            keylet_type_c,
702            buf_read.as_ptr() as _,
703            buf_read.len() as _,
704            arg,
705            0,
706            0,
707            0,
708        )
709    };
710
711    result_u64(res)
712}
713
714#[inline(always)]
715fn buf_read_and_2_args(
716    buf_write: &mut [u8],
717    buf_read: &[u8],
718    arg_1: u32,
719    arg_2: u32,
720    keylet_type_c: u32,
721) -> Result<u64> {
722    let res = unsafe {
723        _c::util_keylet(
724            buf_write.as_mut_ptr() as _,
725            buf_write.len() as _,
726            keylet_type_c,
727            buf_read.as_ptr() as _,
728            buf_read.len() as _,
729            arg_1,
730            arg_2,
731            0,
732            0,
733        )
734    };
735
736    result_u64(res)
737}
738
739#[inline(always)]
740fn buf_2_read_and_zeroes(
741    buf_write: &mut [u8],
742    buf_1_read: &[u8],
743    buf_2_read: &[u8],
744    keylet_type_c: u32,
745) -> Result<u64> {
746    let res = unsafe {
747        _c::util_keylet(
748            buf_write.as_mut_ptr() as _,
749            buf_write.len() as _,
750            keylet_type_c,
751            buf_1_read.as_ptr() as _,
752            buf_1_read.len() as _,
753            buf_2_read.as_ptr() as _,
754            buf_2_read.len() as _,
755            0,
756            0,
757        )
758    };
759
760    result_u64(res)
761}
762
763#[inline(always)]
764fn result_u64(res: i64) -> Result<u64> {
765    match res {
766        res if res >= 0 => Ok(res as _),
767        _ => Err(Error::from_code(res as _)),
768    }
769}
770
771#[inline(always)]
772fn result_xfl(res: i64) -> Result<XFL> {
773    match res {
774        res if res >= 0 => Ok(XFL(res)),
775        _ => Err(Error::from_code(res as _)),
776    }
777}