From e49e9367c0a803de3cc5312d85121dce2aabc6d5 Mon Sep 17 00:00:00 2001 From: Zhaofeng Li Date: Wed, 10 Feb 2021 18:57:14 -0800 Subject: [PATCH] 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. --- src/nix/key.rs | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/nix/key.rs b/src/nix/key.rs index 93217c4..76f22f8 100644 --- a/src/nix/key.rs +++ b/src/nix/key.rs @@ -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 for KeySource { + type Error = String; + + fn try_from(ks: KeySources) -> Result { + 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, + + #[serde(rename = "keyCommand")] + command: Option>, + + #[serde(rename = "keyFile")] + file: Option, +} + #[derive(Debug, Clone, Validate, Serialize, Deserialize)] pub struct Key { #[serde(flatten)]