1use crate::base::{Body, PrivateOptions};
7use crate::crypto;
8use crate::error::Error;
9use crate::options::Options;
10use crate::types::*;
11
12#[cfg(feature = "alloc")]
13use alloc::prelude::v1::*;
14
15pub mod kinds;
16
17pub mod publisher;
19pub use publisher::{DataOptions, Publisher, SecondaryOptions};
20
21pub mod subscriber;
22pub use subscriber::Subscriber;
23
24pub mod net;
25pub use net::Net;
26
27pub mod builder;
28pub use builder::ServiceBuilder;
29
30#[derive(PartialEq, Debug, Clone)]
35#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
36#[cfg_attr(feature = "diesel", derive(diesel::Queryable))]
37pub struct Service {
38 id: Id,
39
40 application_id: u16,
41 kind: PageKind,
42
43 version: u16,
44 data_index: u16,
45
46 body: Body,
47
48 public_options: Vec<Options>,
49 private_options: PrivateOptions,
50
51 public_key: PublicKey,
52 private_key: Option<PrivateKey>,
53
54 encrypted: bool,
55 secret_key: Option<SecretKey>,
56
57 last_sig: Option<Signature>,
58}
59
60impl Default for Service {
61 fn default() -> Service {
63 let (public_key, private_key) = crypto::new_pk().unwrap();
65
66 let id = crypto::hash(&public_key).unwrap().into();
68
69 Service {
71 id,
72 application_id: 0,
73 kind: PageKind::Generic,
74 version: 0,
75 data_index: 0,
76 body: Body::None,
77 public_options: vec![],
78 private_options: PrivateOptions::None,
79 public_key,
80 private_key: Some(private_key),
81 encrypted: false,
82 secret_key: None,
83 last_sig: None,
84 }
85 }
86}
87
88impl Service {
89 pub fn id(&self) -> Id {
90 self.id.clone()
91 }
92
93 pub fn update<U>(&mut self, update_fn: U) -> Result<(), Error>
97 where
98 U: Fn(&mut Body, &mut Vec<Options>, &mut PrivateOptions),
99 {
100 if self.private_key().is_none() {
101 return Err(Error::NoPrivateKey);
102 }
103
104 update_fn(
105 &mut self.body,
106 &mut self.public_options,
107 &mut self.private_options,
108 );
109
110 self.version += 1;
112
113 self.data_index = 0;
115
116 Ok(())
117 }
118
119 pub fn is_origin(&self) -> bool {
120 match (&self.private_key, &self.encrypted, &self.secret_key) {
121 (Some(_), false, _) => true,
122 (Some(_), true, Some(_)) => true,
123 _ => false,
124 }
125 }
126
127 pub fn public_key(&self) -> PublicKey {
128 self.public_key.clone()
129 }
130
131 pub fn private_key(&self) -> Option<PrivateKey> {
132 self.private_key.clone()
133 }
134
135 pub fn secret_key(&self) -> Option<SecretKey> {
136 self.secret_key.clone()
137 }
138
139 pub fn set_private_key(&mut self, key: Option<PrivateKey>) {
140 self.private_key = key;
141 }
142
143 pub fn set_secret_key(&mut self, key: Option<SecretKey>) {
144 self.secret_key = key;
145 }
146}
147
148#[cfg(test)]
149mod test {
150
151 use core::convert::TryInto;
152 use std::net::{Ipv4Addr, SocketAddrV4};
153
154 use crate::base::Base;
155 use crate::page::Page;
156 use crate::service::publisher::{DataOptions, Publisher, SecondaryOptions};
157 use crate::service::subscriber::Subscriber;
158
159 use super::*;
160
161 #[test]
162 fn test_service() {
163 let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
164
165 println!("Creating new service");
166 let service_builder = ServiceBuilder::default()
167 .kind(PageKind::Generic.into())
168 .public_options(vec![Options::name("Test Service")])
169 .private_options(vec![Options::address_v4(socket)].into())
170 .encrypt();
171 let mut service = service_builder.build().unwrap();
172
173 println!("Generating and encoding service page");
174 let mut buff = vec![0u8; 1024];
175 let (n, mut page1) = service
176 .publish_primary(&mut buff)
177 .expect("Error creating page");
178
179 assert_eq!(service.version, 0, "initial service version");
182
183 page1.clean();
185
186 println!("Encoded service to {} bytes", n);
187
188 println!("Decoding service page");
189 let s = service.clone();
190 let pub_key = s.public_key();
191 let sec_key = s.secret_key();
192
193 let (base2, m) = Base::parse(
194 &buff[..n],
195 |_id| Some(pub_key.clone()),
196 |_id| sec_key.clone(),
197 )
198 .expect("Error parsing service page");
199 assert_eq!(n, m);
200 let mut page2: Page = base2
201 .try_into()
202 .expect("Error converting base message to page");
203 page2.raw = None;
204 assert_eq!(page1, page2);
205
206 println!("Generating service replica");
207 let mut replica = Service::load(&page2).expect("Error generating service replica");
208
209 println!("Updating service");
210 service
211 .update(|_body, public_options, _private_options| {
212 public_options.push(Options::kind("Test Kind"));
213 })
214 .expect("Error updating service");
215 assert_eq!(service.version, 1, "service.update updates service version");
216
217 println!("Generating updated page");
218 let (_n, page3) = service
219 .publish_primary(&mut buff)
220 .expect("Error publishing primary page");
221
222 println!("Applying updated page to replica");
223 replica
224 .apply_primary(&page3)
225 .expect("Error updating service replica");
226 assert_eq!(replica.version, 1);
227
228 println!("Generating a secondary page");
229 let secondary_options = SecondaryOptions::default();
230 let (_n, secondary) = service
231 .publish_secondary(&s.id(), secondary_options, &mut buff)
232 .expect("Error publishing secondary page");
233
234 println!("Validating secondary page");
235 service
236 .validate_secondary(&secondary)
237 .expect("Error validating secondary page against publisher");
238
239 println!("Generating a data object");
240 let data_options = DataOptions::default();
241 let (_n, data) = service
242 .publish_data(data_options, &mut buff)
243 .expect("Error publishing data object");
244
245 println!("Validating data object");
246 replica
247 .validate_data(&data)
248 .expect("Error validating data against replica");
249 }
250}