#[cfg(test)]
#[cfg(feature = "tool")]
mod tests;
use serde::{Deserialize, Deserializer, Serialize};
pub const CURRENT_REVISION: u32 = 1;
fn de_revision<'de, D: Deserializer<'de>>(deserializer: D) -> Result<u32, D::Error> {
let rev: u32 = Deserialize::deserialize(deserializer)?;
if rev > 0 {
Ok(rev)
} else {
Err(serde::de::Error::custom(
"revision 0 cannot be explicity specified",
))
}
}
#[derive(Debug, Deserialize, Serialize)]
pub struct PluginInfo {
name: String,
version: String,
#[serde(default)]
#[serde(deserialize_with = "de_revision")]
revision: u32,
}
impl PluginInfo {
pub fn new<N: AsRef<str>, V: AsRef<str>>(name: N, version: V) -> PluginInfo {
PluginInfo {
name: name.as_ref().to_string(),
version: version.as_ref().to_string(),
revision: CURRENT_REVISION,
}
}
pub fn name(&self) -> &str {
&self.name
}
pub fn version(&self) -> &str {
&self.version
}
pub fn revision(&self) -> u32 {
self.revision
}
}
#[cfg(feature = "tool")]
mod tool_impls {
use std::collections::HashMap;
use std::convert::TryFrom;
use crate::info::PluginInfo;
use crate::tool::PluginError::{self, InvalidResponse};
impl TryFrom<HashMap<String, String>> for PluginInfo {
type Error = PluginError;
fn try_from(mut map: HashMap<String, String>) -> Result<Self, PluginError> {
let name = map.remove("name").ok_or(InvalidResponse)?;
let version = map.remove("version").ok_or(InvalidResponse)?;
let revision = map
.remove("revision")
.map_or(Ok(Default::default()), |s| s.parse())
.map_err(|_| InvalidResponse)?;
Ok(PluginInfo {
name,
version,
revision,
})
}
}
}