key: Serialize KeySource through an intermediate struct

Well, still better than `if/else`-ing all the way. Also we
definitely need unit tests.

See #8.
This commit is contained in:
Zhaofeng Li 2021-02-10 18:57:14 -08:00
parent 2886662e18
commit e49e9367c0

View file

@ -1,4 +1,5 @@
use std::{
convert::TryFrom,
io::{self, Cursor},
path::{Path, PathBuf},
process::Stdio,
@ -14,6 +15,7 @@ use tokio::{
use validator::{Validate, ValidationError};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(try_from = "KeySources")]
enum KeySource {
#[serde(rename = "text")]
Text(String),
@ -25,6 +27,38 @@ enum KeySource {
File(PathBuf),
}
impl TryFrom<KeySources> for KeySource {
type Error = String;
fn try_from(ks: KeySources) -> Result<Self, Self::Error> {
match (ks.text, ks.command, ks.file) {
(Some(text), None, None) => {
Ok(KeySource::Text(text))
}
(None, Some(command), None) => {
Ok(KeySource::Command(command))
}
(None, None, Some(file)) => {
Ok(KeySource::File(file))
}
x => {
Err(format!("Somehow 0 or more than 1 key source was specified: {:?}", x))
}
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct KeySources {
text: Option<String>,
#[serde(rename = "keyCommand")]
command: Option<Vec<String>>,
#[serde(rename = "keyFile")]
file: Option<PathBuf>,
}
#[derive(Debug, Clone, Validate, Serialize, Deserialize)]
pub struct Key {
#[serde(flatten)]