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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
// User-facing output things
use std::fmt;
use std::str::FromStr;
use serde::{Deserialize, Serialize};
/// This is used in user-facing CLIs to set the formatting for output,
/// and defaults to text.
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq, Default)]
#[serde(rename_all = "lowercase")]
pub enum ConsoleOutputMode {
#[default]
Text,
JSON,
}
impl FromStr for ConsoleOutputMode {
type Err = &'static str;
/// This can be safely unwrap'd because it'll always return a default of text
/// ```
/// use kanidm_proto::messages::ConsoleOutputMode;
///
/// let mode: ConsoleOutputMode = "🦀".into();
/// assert_eq!(ConsoleOutputMode::Text, mode);
/// let mode: ConsoleOutputMode = "".into();
/// assert_eq!(ConsoleOutputMode::Text, mode);
///
/// let mode: ConsoleOutputMode = "json".into();
/// assert_eq!(ConsoleOutputMode::JSON, mode);
/// ```
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"json" => Ok(ConsoleOutputMode::JSON),
"text" => Ok(ConsoleOutputMode::Text),
_ => {
eprintln!(
"Supplied output mode ({:?}) was invalid, defaulting to text",
s
);
Ok(ConsoleOutputMode::Text)
}
}
}
}
/// This will take any string, if it's 'text' or 'json' then you'll get
/// what you asked for, else you'll get a text version.
///
/// ```
/// use kanidm_proto::messages::ConsoleOutputMode;
/// let bork = "text";
/// let com: ConsoleOutputMode = bork.into();
/// matches!(ConsoleOutputMode::Text, com);
/// ```
impl From<&str> for ConsoleOutputMode {
fn from(input: &str) -> Self {
match ConsoleOutputMode::from_str(input) {
Ok(val) => val,
Err(_) => Self::Text,
}
}
}
/// This will take any string, if it's 'text' or 'json' then you'll get
/// what you asked for, else you'll get a text version.
///
/// ```
/// use kanidm_proto::messages::ConsoleOutputMode;
/// let bork = String::from("cr4bz");
/// let com: ConsoleOutputMode = bork.into();
/// matches!(ConsoleOutputMode::Text, com);
/// ```
impl From<String> for ConsoleOutputMode {
fn from(input: String) -> Self {
match ConsoleOutputMode::from_str(input.as_str()) {
Ok(val) => val,
Err(_) => Self::Text,
}
}
}
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum MessageStatus {
Failure,
Success,
}
impl fmt::Display for MessageStatus {
fn fmt(&self, f: &mut fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> {
match *self {
MessageStatus::Failure => f.write_str("failure"),
MessageStatus::Success => f.write_str("success"),
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct AccountChangeMessage {
#[serde(skip_serializing)]
pub output_mode: ConsoleOutputMode,
pub action: String,
pub result: String,
pub status: MessageStatus,
pub src_user: String,
pub dest_user: String,
}
impl Default for AccountChangeMessage {
fn default() -> Self {
AccountChangeMessage {
output_mode: ConsoleOutputMode::Text,
action: String::from(""),
result: String::from(""),
status: MessageStatus::Success,
src_user: String::from(""),
dest_user: String::from(""),
}
}
}
/// This outputs in either JSON or Text depending on the output_mode setting
/// ```
/// use std::fmt::format;
/// use kanidm_proto::messages::*;
/// let mut msg = AccountChangeMessage::default();
/// msg.action=String::from("cake_eating");
/// msg.src_user=String::from("Kani");
/// msg.dest_user=String::from("Krabby");
/// msg.result=String::from("It was amazing");
/// assert_eq!(msg.status, MessageStatus::Success);
///
/// let expected_result = "success - cake_eating for Krabby: It was amazing";
/// assert_eq!(format!("{}", msg), expected_result);
///
/// msg.output_mode = ConsoleOutputMode::JSON;
/// let expected_result = "{\"action\":\"cake_eating\",\"result\":\"It was amazing\",\"status\":\"success\",\"src_user\":\"Kani\",\"dest_user\":\"Krabby\"}";
/// assert_eq!(format!("{}", msg), expected_result);
/// ```
impl fmt::Display for AccountChangeMessage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.output_mode {
ConsoleOutputMode::JSON => write!(
f,
"{}",
serde_json::to_string(self).unwrap_or(format!("{:?}", self)) /* if it fails to JSON serialize, just debug-dump it */
),
ConsoleOutputMode::Text => write!(
f,
"{} - {} for {}: {}",
self.status, self.action, self.dest_user, self.result,
),
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct BasicMessage {
#[serde(skip_serializing)]
pub output_mode: ConsoleOutputMode,
pub action: String,
pub result: String,
pub status: MessageStatus,
}
impl Default for BasicMessage {
fn default() -> Self {
BasicMessage {
output_mode: ConsoleOutputMode::Text,
action: String::from(""),
result: String::from(""),
status: MessageStatus::Success,
}
}
}
/// This outputs in either JSON or Text depending on the output_mode setting
/// ```
/// use kanidm_proto::messages::*;
/// use std::fmt::format;
/// let mut msg = BasicMessage::default();
/// msg.action = String::from("cake_eating");
/// msg.result = String::from("It was amazing");
/// assert_eq!(msg.status, MessageStatus::Success);
///
/// let expected_result = "success - cake_eating: It was amazing";
/// assert_eq!(format!("{}", msg), expected_result);
///
/// msg.output_mode = ConsoleOutputMode::JSON;
/// let expected_result =
/// "{\"action\":\"cake_eating\",\"result\":\"It was amazing\",\"status\":\"success\"}";
/// assert_eq!(format!("{}", msg), expected_result);
/// ```
impl fmt::Display for BasicMessage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self.output_mode {
ConsoleOutputMode::JSON => write!(
f,
"{}",
serde_json::to_string(self).unwrap_or(format!("{:?}", self)) /* if it fails to JSON serialize, just debug-dump it */
),
ConsoleOutputMode::Text => {
write!(f, "{} - {}: {}", self.status, self.action, self.result,)
}
}
}
}