iota_json_rpc_types/
iota_owner.rs

1// Copyright (c) 2026 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use iota_types::{
5    base_types::{IotaAddress, ObjectID, SequenceNumber},
6    object::Owner,
7};
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10use serde_with::{DeserializeAs, SerializeAs, serde_as};
11
12use crate::iota_primitives::{
13    IotaAddress as IotaAddressSchema, SequenceNumberU64 as SequenceNumberU64Schema,
14};
15
16/// Enum of different types of ownership for an object.
17///
18/// # BCS
19///
20/// The BCS serialized form for this type is defined by the following ABNF:
21///
22/// ```text
23/// owner = owner-address / owner-object / owner-shared / owner-immutable
24///
25/// owner-address   = %x00 address
26/// owner-object    = %x01 object-id
27/// owner-shared    = %x02 u64
28/// owner-immutable = %x03
29/// ```
30#[serde_as]
31#[derive(Serialize, Deserialize, JsonSchema)]
32#[serde(rename = "Owner")]
33pub enum OwnerSchema {
34    /// Object is exclusively owned by a single address, and is mutable.
35    #[schemars(with = "IotaAddressSchema")]
36    AddressOwner(IotaAddress),
37    /// Object is exclusively owned by a single object, and is mutable.
38    /// The object ID is converted to IotaAddress as IotaAddress is
39    /// universal.
40    #[schemars(with = "IotaAddressSchema")]
41    ObjectOwner(IotaAddress),
42    /// Object is shared, can be used by any address, and is mutable.
43    Shared {
44        /// The version at which the object became shared
45        #[schemars(with = "SequenceNumberU64Schema")]
46        initial_shared_version: SequenceNumber,
47    },
48    /// Object is immutable, and hence ownership doesn't matter.
49    Immutable,
50}
51
52impl SerializeAs<Owner> for OwnerSchema {
53    fn serialize_as<S>(source: &Owner, serializer: S) -> Result<S::Ok, S::Error>
54    where
55        S: serde::Serializer,
56    {
57        OwnerSchema::from(*source).serialize(serializer)
58    }
59}
60
61impl<'de> DeserializeAs<'de, Owner> for OwnerSchema {
62    fn deserialize_as<D>(deserializer: D) -> Result<Owner, D::Error>
63    where
64        D: serde::Deserializer<'de>,
65    {
66        let iota_owner = OwnerSchema::deserialize(deserializer)?;
67        Ok(Owner::from(iota_owner))
68    }
69}
70
71impl std::fmt::Display for OwnerSchema {
72    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73        match self {
74            Self::AddressOwner(address) => {
75                write!(f, "Account Address ( {address} )")
76            }
77            Self::ObjectOwner(address) => {
78                write!(f, "Object ID: ( {address} )")
79            }
80            Self::Immutable => {
81                write!(f, "Immutable")
82            }
83            Self::Shared {
84                initial_shared_version,
85            } => {
86                write!(f, "Shared( {initial_shared_version} )")
87            }
88        }
89    }
90}
91
92impl From<Owner> for OwnerSchema {
93    fn from(value: Owner) -> Self {
94        match value {
95            Owner::Address(address) => OwnerSchema::AddressOwner(address),
96            Owner::Object(object_id) => OwnerSchema::ObjectOwner(*object_id.as_address()),
97            Owner::Shared(initial_shared_version) => OwnerSchema::Shared {
98                initial_shared_version,
99            },
100            Owner::Immutable => OwnerSchema::Immutable,
101            _ => unimplemented!("a new Owner enum variant was added and needs to be handled"),
102        }
103    }
104}
105
106impl From<OwnerSchema> for Owner {
107    fn from(value: OwnerSchema) -> Self {
108        match value {
109            OwnerSchema::AddressOwner(address) => Owner::Address(address),
110            OwnerSchema::ObjectOwner(address) => Owner::Object(ObjectID::from(address)),
111            OwnerSchema::Shared {
112                initial_shared_version,
113            } => Owner::Shared(initial_shared_version),
114            OwnerSchema::Immutable => Owner::Immutable,
115        }
116    }
117}