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
// Copyright Amazon.com, Inc. or its affiliates.

//! Provides higher-level APIs for `ION_DECIMAL`

use crate::result::*;
use crate::*;

use std::ops::{Deref, DerefMut};

/// Smart Pointer over `ION_DECIMAL` to ensure that `ion_decimal_free` is invoked on the instance.
pub struct IonDecimalPtr {
    /// Unlike `ION_INT`, we can own the memory of the `ION_DECIMAL` structure itself, but its
    /// underlying components are managed by `ion_decimal_free`.
    value: ION_DECIMAL,
}

impl IonDecimalPtr {
    /// Creates an `ION_DECIMAL` from an `i32`.
    pub fn try_from_i32(value: i32) -> IonCResult<Self> {
        let mut decimal = Self::try_from_existing(ION_DECIMAL::default())?;
        ionc!(ion_decimal_from_int32(decimal.as_mut_ptr(), value))?;
        Ok(decimal)
    }

    /// Creates an `ION_DECIMAL` from a `BigDecimal`.
    pub fn try_from_bigdecimal(value: &BigDecimal) -> IonCResult<Self> {
        let mut decimal = Self::try_from_existing(ION_DECIMAL::default())?;
        decimal.try_assign_bigdecimal(value)?;
        Ok(decimal)
    }

    /// Creates and `ION_DECIMAL` from a `decQuad`.
    pub fn try_from_decquad(value: decQuad) -> IonCResult<Self> {
        let ion_decimal = ION_DECIMAL {
            type_: ION_DECIMAL_TYPE_ION_DECIMAL_TYPE_QUAD,
            value: _ion_decimal__bindgen_ty_1 { quad_value: value },
        };

        Self::try_from_existing(ion_decimal)
    }

    /// Binds an existing `ION_DECIMAL` to a pointer.
    pub fn try_from_existing(value: ION_DECIMAL) -> IonCResult<Self> {
        Ok(Self { value })
    }

    /// Returns the underlying `ION_DECIMAL` as a mutable pointer.
    pub fn as_mut_ptr(&mut self) -> *mut ION_DECIMAL {
        &mut self.value
    }
}

impl Deref for IonDecimalPtr {
    type Target = ION_DECIMAL;

    fn deref(&self) -> &Self::Target {
        &self.value
    }
}

impl DerefMut for IonDecimalPtr {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.value
    }
}

impl Drop for IonDecimalPtr {
    fn drop(&mut self) {
        unsafe {
            ion_decimal_free(&mut self.value);
        }
    }
}