calimero_primitives/
application.rs

1use core::fmt::{self, Display, Formatter};
2use core::ops::Deref;
3use core::str::FromStr;
4
5use serde::{Deserialize, Serialize};
6use thiserror::Error as ThisError;
7use url::{ParseError, Url};
8
9use crate::blobs::BlobId;
10use crate::hash::{Hash, HashError};
11
12#[derive(Copy, Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize, Ord, PartialOrd)]
13#[cfg_attr(
14    feature = "borsh",
15    derive(borsh::BorshDeserialize, borsh::BorshSerialize)
16)]
17// todo! define macros that construct newtypes
18// todo! wrapping Hash<N> with this interface
19pub struct ApplicationId(Hash);
20
21impl From<[u8; 32]> for ApplicationId {
22    fn from(id: [u8; 32]) -> Self {
23        Self(id.into())
24    }
25}
26
27impl AsRef<[u8; 32]> for ApplicationId {
28    fn as_ref(&self) -> &[u8; 32] {
29        &self.0
30    }
31}
32
33impl Deref for ApplicationId {
34    type Target = [u8; 32];
35
36    fn deref(&self) -> &Self::Target {
37        &self.0
38    }
39}
40
41impl ApplicationId {
42    #[must_use]
43    pub fn as_str(&self) -> &str {
44        self.0.as_str()
45    }
46}
47
48impl Display for ApplicationId {
49    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
50        f.pad(self.as_str())
51    }
52}
53
54impl From<ApplicationId> for String {
55    fn from(id: ApplicationId) -> Self {
56        id.as_str().to_owned()
57    }
58}
59
60impl From<&ApplicationId> for String {
61    fn from(id: &ApplicationId) -> Self {
62        id.as_str().to_owned()
63    }
64}
65
66#[derive(Clone, Copy, Debug, ThisError)]
67#[error(transparent)]
68pub struct InvalidApplicationId(HashError);
69
70impl FromStr for ApplicationId {
71    type Err = InvalidApplicationId;
72
73    fn from_str(s: &str) -> Result<Self, Self::Err> {
74        Ok(Self(s.parse().map_err(InvalidApplicationId)?))
75    }
76}
77
78#[derive(Clone, Debug, Deserialize, Serialize)]
79pub struct ApplicationSource(Url);
80
81impl FromStr for ApplicationSource {
82    type Err = ParseError;
83
84    fn from_str(s: &str) -> Result<Self, Self::Err> {
85        s.parse().map(Self)
86    }
87}
88
89impl From<Url> for ApplicationSource {
90    fn from(value: Url) -> Self {
91        Self(value)
92    }
93}
94
95impl From<ApplicationSource> for Url {
96    fn from(value: ApplicationSource) -> Self {
97        value.0
98    }
99}
100
101impl Display for ApplicationSource {
102    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
103        Display::fmt(&self.0, f)
104    }
105}
106
107#[derive(Copy, Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)]
108#[cfg_attr(
109    feature = "borsh",
110    derive(borsh::BorshDeserialize, borsh::BorshSerialize)
111)]
112pub struct ApplicationBlob {
113    pub bytecode: BlobId,
114    pub compiled: BlobId,
115}
116
117#[derive(Clone, Debug, Deserialize, Serialize)]
118#[non_exhaustive]
119pub struct Application {
120    pub id: ApplicationId,
121    pub blob: ApplicationBlob,
122    pub size: u64,
123    pub source: ApplicationSource,
124    pub metadata: Vec<u8>,
125}
126
127impl Application {
128    #[must_use]
129    pub const fn new(
130        id: ApplicationId,
131        blob: ApplicationBlob,
132        size: u64,
133        source: ApplicationSource,
134        metadata: Vec<u8>,
135    ) -> Self {
136        Self {
137            id,
138            blob,
139            size,
140            source,
141            metadata,
142        }
143    }
144}