scale_info/ty/
composite.rs

1// Copyright 2019-2022 Parity Technologies (UK) Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::prelude::vec::Vec;
16
17use crate::{
18    form::{Form, MetaForm, PortableForm},
19    Field, IntoPortable, Registry,
20};
21use derive_more::From;
22use scale::Encode;
23#[cfg(feature = "serde")]
24use serde::{de::DeserializeOwned, Deserialize, Serialize};
25
26/// A composite type, consisting of either named (struct) or unnamed (tuple
27/// struct) fields
28///
29/// # Examples
30///
31/// ## A Rust struct with named fields.
32///
33/// ```
34/// struct Person {
35///     name: String,
36///     age_in_years: u8,
37///     friends: Vec<Person>,
38/// }
39/// ```
40///
41/// ## A tuple struct with unnamed fields.
42///
43/// ```
44/// struct Color(u8, u8, u8);
45/// ```
46///
47/// ## A so-called unit struct
48///
49/// ```
50/// struct JustAMarker;
51/// ```
52#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
53#[cfg_attr(
54    feature = "serde",
55    serde(bound(
56        serialize = "T::Type: Serialize, T::String: Serialize",
57        deserialize = "T::Type: DeserializeOwned, T::String: DeserializeOwned",
58    ))
59)]
60#[cfg_attr(feature = "serde", serde(rename_all = "lowercase"))]
61#[cfg_attr(any(feature = "std", feature = "decode"), derive(scale::Decode))]
62#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
63#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Debug, From, Encode)]
64pub struct TypeDefComposite<T: Form = MetaForm> {
65    /// The fields of the composite type.
66    #[cfg_attr(
67        feature = "serde",
68        serde(skip_serializing_if = "Vec::is_empty", default)
69    )]
70    pub fields: Vec<Field<T>>,
71}
72
73impl IntoPortable for TypeDefComposite {
74    type Output = TypeDefComposite<PortableForm>;
75
76    fn into_portable(self, registry: &mut Registry) -> Self::Output {
77        TypeDefComposite {
78            fields: registry.map_into_portable(self.fields),
79        }
80    }
81}
82
83impl<T> TypeDefComposite<T>
84where
85    T: Form,
86{
87    /// Creates a new struct definition with named fields.
88    pub fn new<I>(fields: I) -> Self
89    where
90        I: IntoIterator<Item = Field<T>>,
91    {
92        Self {
93            fields: fields.into_iter().collect(),
94        }
95    }
96}
97
98impl<T> TypeDefComposite<T>
99where
100    T: Form,
101{
102    /// Returns the fields of the composite type.
103    #[deprecated(
104        since = "2.5.0",
105        note = "Prefer to access the fields directly; this getter will be removed in the next major version"
106    )]
107    pub fn fields(&self) -> &[Field<T>] {
108        &self.fields
109    }
110}