blob: fd7eaf0d80b4cbc1b66158823bef86d880a97988 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use serde::{Deserialize, Serialize};
pub type File = String;
pub type FidlLibraryName = String;
pub type CcLibraryName = String;
pub type BanjoLibraryName = String;
/// Shortcut for adding fmt::Display and FromStr to an enumeration.
///
/// fmt::Display is used to enable printing the values as they would be
/// serialized. Without it, the enum values can be printed in Debug mode, which
/// outputs the value as defined in the Rust object but ignores any serde
/// annotations that would be applied to the value during serialization.
///
/// FromStr is required by any enums that also derive argh::FromArgs. FromArgs
/// converts a command-line input, which is a String, into the enumeration
/// value to be loaded into the argh-backed structure. All ffx plugin code uses
/// this functionality, so any enums used in ffx plugin command args require
/// this.
///
/// Both are also useful for testing purposes, as they enable quick conversions
/// in the test code to and from string literals which match the json text that
/// would generate the same values.
///
/// Usage: define an enum, then add `display_impl!(TypeName);` alongside any
/// other impl blocks you may have for that type.
///
/// Note: the enumeration must also derive serde Serialize and Deserialize.
/// Also be aware that either of these implementations will fail if the
/// underlying Serialize/Deserialize functions generate errors. This should
/// only ever be a possibility with custom implementations, or if an
/// enumeration variant has an associated value that fails (such as a map with
/// non-string keys).
#[macro_export]
macro_rules! display_impl {
($enum:ty) => {
impl std::fmt::Display for $enum {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let trim: &[char] = &['"'];
write!(f, "{}", serde_json::to_value(self).unwrap().to_string().trim_matches(trim))
}
}
impl std::str::FromStr for $enum {
type Err = anyhow::Error;
fn from_str(text: &str) -> anyhow::Result<Self> {
use anyhow::Context;
serde_json::from_str(&format!("\"{}\"", text)).with_context(|| {
format!(
"could not parse '{}' as a valid {}. \
Please check the help text for allowed values and try again",
text,
std::any::type_name::<$enum>()
)
})
}
}
};
}
#[derive(Serialize, Deserialize, Debug, Hash, Clone, PartialOrd, Ord, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum CpuArchitecture {
Arm64,
X64,
Unsupported,
}
impl Default for CpuArchitecture {
fn default() -> Self {
CpuArchitecture::X64
}
}
impl From<String> for CpuArchitecture {
fn from(item: String) -> Self {
CpuArchitecture::from(&item[..])
}
}
impl From<&str> for CpuArchitecture {
fn from(item: &str) -> Self {
match item {
// Values based on https://doc.rust-lang.org/std/env/consts/constant.ARCH.html.
"aarch64" => Self::Arm64,
"x86_64" => Self::X64,
// Values from deserialization.
"arm64" => Self::Arm64,
"x64" => Self::X64,
_ => Self::Unsupported,
}
}
}
display_impl!(CpuArchitecture);
#[derive(Serialize, Deserialize, Debug, Hash, Clone, PartialOrd, Ord, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum PointingDevice {
Mouse,
None,
Touch,
}
impl Default for PointingDevice {
fn default() -> Self {
PointingDevice::None
}
}
display_impl!(PointingDevice);
#[derive(Serialize, Deserialize, Debug, Hash, Clone, PartialOrd, Ord, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum ScreenUnits {
Pixels,
}
impl Default for ScreenUnits {
fn default() -> Self {
ScreenUnits::Pixels
}
}
display_impl!(ScreenUnits);
#[derive(Serialize, Deserialize, Debug, Hash, Clone, PartialOrd, Ord, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum DataUnits {
Bytes,
Kilobytes,
Megabytes,
Gigabytes,
Terabytes,
}
impl Default for DataUnits {
fn default() -> Self {
DataUnits::Bytes
}
}
display_impl!(DataUnits);
impl DataUnits {
/// This function provides an alternative output to the full string returned by fmt::Display.
/// The fmt::Display version is necessary for Serialization, while the abbreviated value is
/// needed for certain command-line conversions. Note that this diverges from Fuchsia's
/// convention of using MiB, KiB, etc. because these abbreviations are intended for legacy
/// compatibility with the Qemu and FVM tool command lines.
pub fn abbreviate(&self) -> &str {
match self {
DataUnits::Bytes => "",
DataUnits::Kilobytes => "K",
DataUnits::Megabytes => "M",
DataUnits::Gigabytes => "G",
DataUnits::Terabytes => "T",
}
}
}
#[derive(Serialize, Deserialize, Debug, Hash, Clone, PartialOrd, Ord, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum AudioModel {
AC97,
AdLib,
Cs4231A,
ES1370,
Gus,
Hda,
None,
PcSpk,
SB16,
}
impl Default for AudioModel {
fn default() -> Self {
AudioModel::None
}
}
display_impl!(AudioModel);
#[derive(Serialize, Deserialize, Debug, Hash, PartialEq, Eq, Clone, PartialOrd, Ord)]
#[serde(rename_all = "snake_case")]
pub enum ElementType {
BanjoLibrary,
CcPrebuiltLibrary,
CcSourceLibrary,
Config,
DartLibrary,
Documentation,
FidlLibrary,
HostTool,
License,
LoadableModule,
PhysicalDevice,
ProductBundle,
ProductBundleContainer,
Sysroot,
VirtualDevice,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[serde(deny_unknown_fields)]
pub struct Envelope<D> {
/// The value of the $id field of the schema constraining the envelope.
pub schema_id: String,
pub data: D,
}