1pub mod account_root;
2pub mod current_escrow;
3pub mod escrow;
4pub mod nft;
5pub mod traits;
6
7use crate::core::types::account_id::{ACCOUNT_ID_SIZE, AccountID};
8use crate::core::types::amount::Amount;
9use crate::core::types::blob::Blob;
10use crate::core::types::uint::{HASH128_SIZE, HASH256_SIZE, Hash128, Hash256};
11use crate::host::error_codes::{
12 match_result_code, match_result_code_optional, match_result_code_with_expected_bytes,
13 match_result_code_with_expected_bytes_optional,
14};
15use crate::host::{Result, get_current_ledger_obj_field, get_ledger_obj_field};
16
17pub trait FieldGetter: Sized {
63 fn get_from_current_ledger_obj(field_code: i32) -> Result<Self>;
75
76 fn get_from_current_ledger_obj_optional(field_code: i32) -> Result<Option<Self>>;
89
90 fn get_from_ledger_obj(register_num: i32, field_code: i32) -> Result<Self>;
103
104 fn get_from_ledger_obj_optional(register_num: i32, field_code: i32) -> Result<Option<Self>>;
118}
119
120impl FieldGetter for u16 {
130 fn get_from_current_ledger_obj(field_code: i32) -> Result<Self> {
131 let mut value: u16 = 0;
132 let value_ptr: *mut u8 = (&mut value as *mut u16).cast::<u8>();
133 let result_code = unsafe { get_current_ledger_obj_field(field_code, value_ptr, 2) };
134 match_result_code_with_expected_bytes(result_code, 2, || value)
135 }
136
137 fn get_from_current_ledger_obj_optional(field_code: i32) -> Result<Option<Self>> {
138 let mut value: u16 = 0;
139 let value_ptr: *mut u8 = (&mut value as *mut u16).cast::<u8>();
140 let result_code = unsafe { get_current_ledger_obj_field(field_code, value_ptr, 2) };
141 match_result_code_with_expected_bytes_optional(result_code, 2, || Some(value))
142 }
143
144 fn get_from_ledger_obj(register_num: i32, field_code: i32) -> Result<Self> {
145 let mut value: u16 = 0;
146 let value_ptr: *mut u8 = (&mut value as *mut u16).cast::<u8>();
147 let result_code = unsafe { get_ledger_obj_field(register_num, field_code, value_ptr, 2) };
148 match_result_code_with_expected_bytes(result_code, 2, || value)
149 }
150
151 fn get_from_ledger_obj_optional(register_num: i32, field_code: i32) -> Result<Option<Self>> {
152 let mut value: u16 = 0;
153 let value_ptr: *mut u8 = (&mut value as *mut u16).cast::<u8>();
154 let result_code = unsafe { get_ledger_obj_field(register_num, field_code, value_ptr, 2) };
155 match_result_code_with_expected_bytes_optional(result_code, 2, || Some(value))
156 }
157}
158
159impl FieldGetter for u32 {
169 fn get_from_current_ledger_obj(field_code: i32) -> Result<Self> {
170 let mut value: u32 = 0;
171 let value_ptr: *mut u8 = (&mut value as *mut u32).cast::<u8>();
172 let result_code = unsafe { get_current_ledger_obj_field(field_code, value_ptr, 4) };
173 match_result_code_with_expected_bytes(result_code, 4, || value)
174 }
175
176 fn get_from_current_ledger_obj_optional(field_code: i32) -> Result<Option<Self>> {
177 let mut value: u32 = 0;
178 let value_ptr: *mut u8 = (&mut value as *mut u32).cast::<u8>();
179 let result_code = unsafe { get_current_ledger_obj_field(field_code, value_ptr, 4) };
180 match_result_code_with_expected_bytes_optional(result_code, 4, || Some(value))
181 }
182
183 fn get_from_ledger_obj(register_num: i32, field_code: i32) -> Result<Self> {
184 let mut value: u32 = 0;
185 let value_ptr: *mut u8 = (&mut value as *mut u32).cast::<u8>();
186 let result_code = unsafe { get_ledger_obj_field(register_num, field_code, value_ptr, 4) };
187 match_result_code_with_expected_bytes(result_code, 4, || value)
188 }
189
190 fn get_from_ledger_obj_optional(register_num: i32, field_code: i32) -> Result<Option<Self>> {
191 let mut value: u32 = 0;
192 let value_ptr: *mut u8 = (&mut value as *mut u32).cast::<u8>();
193 let result_code = unsafe { get_ledger_obj_field(register_num, field_code, value_ptr, 4) };
194 match_result_code_with_expected_bytes_optional(result_code, 4, || Some(value))
195 }
196}
197
198impl FieldGetter for u64 {
209 fn get_from_current_ledger_obj(field_code: i32) -> Result<Self> {
210 let mut value: u64 = 0;
211 let value_ptr: *mut u8 = (&mut value as *mut u64).cast::<u8>();
212 let result_code = unsafe { get_current_ledger_obj_field(field_code, value_ptr, 8) };
213 match_result_code_with_expected_bytes(result_code, 8, || value)
214 }
215
216 fn get_from_current_ledger_obj_optional(field_code: i32) -> Result<Option<Self>> {
217 let mut value: u64 = 0;
218 let value_ptr: *mut u8 = (&mut value as *mut u64).cast::<u8>();
219 let result_code = unsafe { get_current_ledger_obj_field(field_code, value_ptr, 8) };
220 match_result_code_with_expected_bytes_optional(result_code, 8, || Some(value))
221 }
222
223 fn get_from_ledger_obj(register_num: i32, field_code: i32) -> Result<Self> {
224 let mut value: u64 = 0;
225 let value_ptr: *mut u8 = (&mut value as *mut u64).cast::<u8>();
226 let result_code = unsafe { get_ledger_obj_field(register_num, field_code, value_ptr, 8) };
227 match_result_code_with_expected_bytes(result_code, 8, || value)
228 }
229
230 fn get_from_ledger_obj_optional(register_num: i32, field_code: i32) -> Result<Option<Self>> {
231 let mut value: u64 = 0;
232 let value_ptr: *mut u8 = (&mut value as *mut u64).cast::<u8>();
233 let result_code = unsafe { get_ledger_obj_field(register_num, field_code, value_ptr, 8) };
234 match_result_code_with_expected_bytes_optional(result_code, 8, || Some(value))
235 }
236}
237
238impl FieldGetter for AccountID {
250 fn get_from_current_ledger_obj(field_code: i32) -> Result<Self> {
251 let mut buffer = [0x00; ACCOUNT_ID_SIZE];
252 let result_code = unsafe {
253 get_current_ledger_obj_field(field_code, buffer.as_mut_ptr(), ACCOUNT_ID_SIZE)
254 };
255 match_result_code_with_expected_bytes(result_code, ACCOUNT_ID_SIZE, || buffer.into())
256 }
257
258 fn get_from_current_ledger_obj_optional(field_code: i32) -> Result<Option<Self>> {
259 let mut buffer = [0x00; ACCOUNT_ID_SIZE];
260 let result_code = unsafe {
261 get_current_ledger_obj_field(field_code, buffer.as_mut_ptr(), ACCOUNT_ID_SIZE)
262 };
263 match_result_code_with_expected_bytes_optional(result_code, ACCOUNT_ID_SIZE, || {
264 Some(buffer.into())
265 })
266 }
267
268 fn get_from_ledger_obj(register_num: i32, field_code: i32) -> Result<Self> {
269 let mut buffer = [0x00; ACCOUNT_ID_SIZE];
270 let result_code = unsafe {
271 get_ledger_obj_field(
272 register_num,
273 field_code,
274 buffer.as_mut_ptr(),
275 ACCOUNT_ID_SIZE,
276 )
277 };
278 match_result_code_with_expected_bytes(result_code, ACCOUNT_ID_SIZE, || buffer.into())
279 }
280
281 fn get_from_ledger_obj_optional(register_num: i32, field_code: i32) -> Result<Option<Self>> {
282 let mut buffer = [0x00; ACCOUNT_ID_SIZE];
283 let result_code = unsafe {
284 get_ledger_obj_field(
285 register_num,
286 field_code,
287 buffer.as_mut_ptr(),
288 ACCOUNT_ID_SIZE,
289 )
290 };
291 match_result_code_with_expected_bytes_optional(result_code, ACCOUNT_ID_SIZE, || {
292 Some(buffer.into())
293 })
294 }
295}
296
297impl FieldGetter for Amount {
309 fn get_from_current_ledger_obj(field_code: i32) -> Result<Self> {
310 const BUFFER_SIZE: usize = 48;
311 let mut buffer = [0u8; BUFFER_SIZE];
312 let result_code =
313 unsafe { get_current_ledger_obj_field(field_code, buffer.as_mut_ptr(), BUFFER_SIZE) };
314 match_result_code(result_code, || Amount::from(buffer))
315 }
316
317 fn get_from_current_ledger_obj_optional(field_code: i32) -> Result<Option<Self>> {
318 const BUFFER_SIZE: usize = 48;
319 let mut buffer = [0u8; BUFFER_SIZE];
320 let result_code =
321 unsafe { get_current_ledger_obj_field(field_code, buffer.as_mut_ptr(), BUFFER_SIZE) };
322 match_result_code_optional(result_code, || Some(Amount::from(buffer)))
323 }
324
325 fn get_from_ledger_obj(register_num: i32, field_code: i32) -> Result<Self> {
326 const BUFFER_SIZE: usize = 48;
327 let mut buffer = [0u8; BUFFER_SIZE];
328 let result_code = unsafe {
329 get_ledger_obj_field(register_num, field_code, buffer.as_mut_ptr(), BUFFER_SIZE)
330 };
331 match_result_code(result_code, || Amount::from(buffer))
332 }
333
334 fn get_from_ledger_obj_optional(register_num: i32, field_code: i32) -> Result<Option<Self>> {
335 const BUFFER_SIZE: usize = 48;
336 let mut buffer = [0u8; BUFFER_SIZE];
337 let result_code = unsafe {
338 get_ledger_obj_field(register_num, field_code, buffer.as_mut_ptr(), BUFFER_SIZE)
339 };
340 match_result_code_optional(result_code, || Some(Amount::from(buffer)))
341 }
342}
343
344impl FieldGetter for Hash128 {
355 fn get_from_current_ledger_obj(field_code: i32) -> Result<Self> {
356 let mut buffer = [0u8; HASH128_SIZE];
357 let result_code =
358 unsafe { get_current_ledger_obj_field(field_code, buffer.as_mut_ptr(), HASH128_SIZE) };
359 match_result_code_with_expected_bytes(result_code, HASH128_SIZE, || Hash128::from(buffer))
360 }
361
362 fn get_from_current_ledger_obj_optional(field_code: i32) -> Result<Option<Self>> {
363 let mut buffer = [0u8; HASH128_SIZE];
364 let result_code =
365 unsafe { get_current_ledger_obj_field(field_code, buffer.as_mut_ptr(), HASH128_SIZE) };
366 match_result_code_with_expected_bytes_optional(result_code, HASH128_SIZE, || {
367 Some(Hash128::from(buffer))
368 })
369 }
370
371 fn get_from_ledger_obj(register_num: i32, field_code: i32) -> Result<Self> {
372 let mut buffer = [0u8; HASH128_SIZE];
373 let result_code = unsafe {
374 get_ledger_obj_field(register_num, field_code, buffer.as_mut_ptr(), HASH128_SIZE)
375 };
376 match_result_code_with_expected_bytes(result_code, HASH128_SIZE, || Hash128::from(buffer))
377 }
378
379 fn get_from_ledger_obj_optional(register_num: i32, field_code: i32) -> Result<Option<Self>> {
380 let mut buffer = [0u8; HASH128_SIZE];
381 let result_code = unsafe {
382 get_ledger_obj_field(register_num, field_code, buffer.as_mut_ptr(), HASH128_SIZE)
383 };
384 match_result_code_with_expected_bytes_optional(result_code, HASH128_SIZE, || {
385 Some(Hash128::from(buffer))
386 })
387 }
388}
389
390impl FieldGetter for Hash256 {
401 fn get_from_current_ledger_obj(field_code: i32) -> Result<Self> {
402 let mut buffer = [0u8; HASH256_SIZE];
403 let result_code =
404 unsafe { get_current_ledger_obj_field(field_code, buffer.as_mut_ptr(), HASH256_SIZE) };
405 match_result_code_with_expected_bytes(result_code, HASH256_SIZE, || Hash256::from(buffer))
406 }
407
408 fn get_from_current_ledger_obj_optional(field_code: i32) -> Result<Option<Self>> {
409 let mut buffer = [0u8; HASH256_SIZE];
410 let result_code =
411 unsafe { get_current_ledger_obj_field(field_code, buffer.as_mut_ptr(), HASH256_SIZE) };
412 match_result_code_with_expected_bytes_optional(result_code, HASH256_SIZE, || {
413 Some(Hash256::from(buffer))
414 })
415 }
416
417 fn get_from_ledger_obj(register_num: i32, field_code: i32) -> Result<Self> {
418 let mut buffer = [0u8; HASH256_SIZE];
419 let result_code = unsafe {
420 get_ledger_obj_field(register_num, field_code, buffer.as_mut_ptr(), HASH256_SIZE)
421 };
422 match_result_code_with_expected_bytes(result_code, HASH256_SIZE, || Hash256::from(buffer))
423 }
424
425 fn get_from_ledger_obj_optional(register_num: i32, field_code: i32) -> Result<Option<Self>> {
426 let mut buffer = [0u8; HASH256_SIZE];
427 let result_code = unsafe {
428 get_ledger_obj_field(register_num, field_code, buffer.as_mut_ptr(), HASH256_SIZE)
429 };
430 match_result_code_with_expected_bytes_optional(result_code, HASH256_SIZE, || {
431 Some(Hash256::from(buffer))
432 })
433 }
434}
435
436const BLOB_BUFFER_SIZE: usize = 1024;
437
438impl FieldGetter for Blob {
451 fn get_from_current_ledger_obj(field_code: i32) -> Result<Self> {
452 let mut buffer = [0u8; BLOB_BUFFER_SIZE];
453 let result_code = unsafe {
454 get_current_ledger_obj_field(field_code, buffer.as_mut_ptr(), BLOB_BUFFER_SIZE)
455 };
456 match_result_code(result_code, || Blob {
457 data: buffer,
458 len: result_code as usize,
459 })
460 }
461
462 fn get_from_current_ledger_obj_optional(field_code: i32) -> Result<Option<Self>> {
463 let mut buffer = [0u8; BLOB_BUFFER_SIZE];
464 let result_code = unsafe {
465 get_current_ledger_obj_field(field_code, buffer.as_mut_ptr(), BLOB_BUFFER_SIZE)
466 };
467 match_result_code_optional(result_code, || {
468 Some(Blob {
469 data: buffer,
470 len: result_code as usize,
471 })
472 })
473 }
474
475 fn get_from_ledger_obj(register_num: i32, field_code: i32) -> Result<Self> {
476 let mut buffer = [0u8; BLOB_BUFFER_SIZE];
477 let result_code = unsafe {
478 get_ledger_obj_field(
479 register_num,
480 field_code,
481 buffer.as_mut_ptr(),
482 BLOB_BUFFER_SIZE,
483 )
484 };
485 match_result_code(result_code, || Blob {
486 data: buffer,
487 len: result_code as usize,
488 })
489 }
490
491 fn get_from_ledger_obj_optional(register_num: i32, field_code: i32) -> Result<Option<Self>> {
492 let mut buffer = [0u8; BLOB_BUFFER_SIZE];
493 let result_code = unsafe {
494 get_ledger_obj_field(
495 register_num,
496 field_code,
497 buffer.as_mut_ptr(),
498 BLOB_BUFFER_SIZE,
499 )
500 };
501 match_result_code_optional(result_code, || {
502 Some(Blob {
503 data: buffer,
504 len: result_code as usize,
505 })
506 })
507 }
508}
509
510pub mod current_ledger_object {
511 use super::FieldGetter;
512 use crate::host::Result;
513
514 #[inline]
526 pub fn get_field<T: FieldGetter>(field_code: i32) -> Result<T> {
527 T::get_from_current_ledger_obj(field_code)
528 }
529
530 #[inline]
543 pub fn get_field_optional<T: FieldGetter>(field_code: i32) -> Result<Option<T>> {
544 T::get_from_current_ledger_obj_optional(field_code)
545 }
546}
547
548pub mod ledger_object {
549 use super::FieldGetter;
550 use crate::host::Result;
551
552 #[inline]
565 pub fn get_field<T: FieldGetter>(register_num: i32, field_code: i32) -> Result<T> {
566 T::get_from_ledger_obj(register_num, field_code)
567 }
568
569 #[inline]
583 pub fn get_field_optional<T: FieldGetter>(
584 register_num: i32,
585 field_code: i32,
586 ) -> Result<Option<T>> {
587 T::get_from_ledger_obj_optional(register_num, field_code)
588 }
589}
590
591#[cfg(test)]
592mod tests {
593 use super::ledger_object;
594 use crate::sfield;
595
596 #[test]
597 fn test_get_field_compilation() {
598 let slot = 0;
603
604 let _balance_call = || -> crate::host::Result<u64> {
606 ledger_object::get_field::<u64>(slot, sfield::Balance)
607 };
608
609 let _sequence_call = || -> crate::host::Result<u32> {
610 ledger_object::get_field::<u32>(slot, sfield::Sequence)
611 };
612
613 let _account_call = || -> crate::host::Result<crate::core::types::account_id::AccountID> {
615 ledger_object::get_field(slot, sfield::Account)
616 };
617
618 let _amount_call = || -> crate::host::Result<crate::core::types::amount::Amount> {
619 ledger_object::get_field(slot, sfield::Amount)
620 };
621
622 let _optional_balance_call = || -> crate::host::Result<Option<u64>> {
624 ledger_object::get_field_optional::<u64>(slot, sfield::Balance)
625 };
626
627 let _optional_sequence_call = || -> crate::host::Result<Option<u32>> {
628 ledger_object::get_field_optional::<u32>(slot, sfield::Sequence)
629 };
630 }
631
632 #[test]
633 fn test_exact_user_pattern() {
634 let slot = 0;
636
637 let _balance = ledger_object::get_field::<u64>(slot, sfield::Balance);
639 let _sequence = ledger_object::get_field::<u32>(slot, sfield::Sequence);
640
641 let _balance_amount =
643 ledger_object::get_field::<crate::core::types::amount::Amount>(slot, sfield::Balance);
644 }
645}