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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
#[allow(clippy::module_name_repetitions)]
pub struct Meta<'a> {
pub app_id: &'a str,
/// App name is shown in the launcher in the list of apps.
pub app_name: &'a str,
pub author_id: &'a str,
pub author_name: &'a str,
/// Launcher is the app that starts first when runtime is launched.
pub launcher: bool,
/// Let the app to use privileged and dangerous runtime API.
pub sudo: bool,
}
impl<'a> Meta<'a> {
/// Load metadata from bytes generated by [`Meta::encode`].
///
/// # Errors
///
/// May return an error if the buffer does not contain valid metadata.
pub fn decode(s: &'a [u8]) -> Result<Self, postcard::Error> {
postcard::from_bytes(s)
}
/// Encode the matadata using the buffer.
///
/// The buffer is required to avoid allocations on the crate side.
/// Use [`Meta::size`] to calculate the required buffer size.
///
/// # Errors
///
/// May return an error if the buffer is no big enough.
pub fn encode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b mut [u8], postcard::Error> {
postcard::to_slice(self, buf)
}
/// Calculate the buffer size required to encode the meta.
#[must_use]
#[allow(clippy::missing_panics_doc)]
pub fn size(&self) -> usize {
let flavor = postcard::ser_flavors::Size::default();
postcard::serialize_with_flavor(self, flavor).unwrap()
}
}
/// A struct with only a few safe fields from Meta.
///
/// It is used to serialize information about an app outside of the app dir.
/// Since it is outside, it escapes the hash and signature checks
/// and so it must not store any information that must be verified before use.
#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
#[allow(clippy::module_name_repetitions)]
pub struct ShortMeta<'a> {
pub app_id: &'a str,
pub author_id: &'a str,
}
impl<'a> ShortMeta<'a> {
/// Load metadata from bytes generated by [`ShortMeta::encode`].
///
/// # Errors
///
/// May return an error if the buffer does not contain valid metadata.
pub fn decode(s: &'a [u8]) -> Result<Self, postcard::Error> {
postcard::from_bytes(s)
}
/// Encode the matadata using the buffer.
///
/// The buffer is required to avoid allocations on the crate side.
/// Use [`ShortMeta::size`] to calculate the required buffer size.
///
/// # Errors
///
/// May return an error if the buffer is no big enough.
pub fn encode<'b>(&self, buf: &'b mut [u8]) -> Result<&'b mut [u8], postcard::Error> {
postcard::to_slice(self, buf)
}
/// Calculate the buffer size required to encode the meta.
#[must_use]
#[allow(clippy::missing_panics_doc)]
pub fn size(&self) -> usize {
let flavor = postcard::ser_flavors::Size::default();
postcard::serialize_with_flavor(self, flavor).unwrap()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_roundtrip() {
let given = Meta {
app_id: "some-app-id",
app_name: "Some App Name",
author_id: "some-author-id",
author_name: "Some Author Name",
launcher: false,
sudo: false,
};
let mut buf = vec![0; given.size()];
let raw = given.encode(&mut buf).unwrap();
let actual = Meta::decode(raw).unwrap();
assert_eq!(given, actual);
}
}