|
| 1 | +use regex::Regex; |
| 2 | +use std::fs::File; |
| 3 | +use std::io::Write; |
| 4 | +use std::io::{Error, ErrorKind}; |
| 5 | +use std::path::PathBuf; |
| 6 | +use std::str::FromStr; |
| 7 | + |
| 8 | +use crate::spaces::FuncSpace; |
| 9 | + |
| 10 | +#[derive(Debug, Clone)] |
| 11 | +pub enum Format { |
| 12 | + Cbor, |
| 13 | + Json, |
| 14 | + Toml, |
| 15 | + Yaml, |
| 16 | +} |
| 17 | + |
| 18 | +impl Format { |
| 19 | + pub fn all() -> &'static [&'static str] { |
| 20 | + &["cbor", "json", "toml", "yaml"] |
| 21 | + } |
| 22 | +} |
| 23 | + |
| 24 | +impl FromStr for Format { |
| 25 | + type Err = String; |
| 26 | + |
| 27 | + fn from_str(format: &str) -> Result<Self, Self::Err> { |
| 28 | + match format { |
| 29 | + "cbor" => Ok(Format::Cbor), |
| 30 | + "json" => Ok(Format::Json), |
| 31 | + "toml" => Ok(Format::Toml), |
| 32 | + "yaml" => Ok(Format::Yaml), |
| 33 | + format => Err(format!("{:?} is not a supported format", format)), |
| 34 | + } |
| 35 | + } |
| 36 | +} |
| 37 | + |
| 38 | +pub(crate) fn dump_formats( |
| 39 | + space: &FuncSpace, |
| 40 | + path: &PathBuf, |
| 41 | + output_path: &Option<PathBuf>, |
| 42 | + output_format: Format, |
| 43 | + pretty: bool, |
| 44 | +) -> std::io::Result<()> { |
| 45 | + if output_path.is_none() { |
| 46 | + let stdout = std::io::stdout(); |
| 47 | + let mut stdout = stdout.lock(); |
| 48 | + |
| 49 | + match output_format { |
| 50 | + Format::Cbor => Err(Error::new( |
| 51 | + ErrorKind::Other, |
| 52 | + "Cbor format cannot be printed to stdout", |
| 53 | + )), |
| 54 | + Format::Json => { |
| 55 | + let json_data = if pretty { |
| 56 | + serde_json::to_string_pretty(&space).unwrap() |
| 57 | + } else { |
| 58 | + serde_json::to_string(&space).unwrap() |
| 59 | + }; |
| 60 | + write!(stdout, "{}", json_data) |
| 61 | + } |
| 62 | + Format::Toml => { |
| 63 | + let toml_data = if pretty { |
| 64 | + toml::to_string_pretty(&space).unwrap() |
| 65 | + } else { |
| 66 | + toml::to_string(&space).unwrap() |
| 67 | + }; |
| 68 | + write!(stdout, "{}", toml_data) |
| 69 | + } |
| 70 | + Format::Yaml => write!(stdout, "{}", serde_yaml::to_string(&space).unwrap()), |
| 71 | + } |
| 72 | + } else { |
| 73 | + let format_ext = match output_format { |
| 74 | + Format::Cbor => ".cbor", |
| 75 | + Format::Json => ".json", |
| 76 | + Format::Toml => ".toml", |
| 77 | + Format::Yaml => ".yml", |
| 78 | + }; |
| 79 | + |
| 80 | + let output_path = output_path.as_ref().unwrap(); |
| 81 | + |
| 82 | + let mut file = path.as_path().file_name().unwrap().to_os_string(); |
| 83 | + file.push(format_ext); |
| 84 | + |
| 85 | + let mut format_path = output_path.clone(); |
| 86 | + format_path.push(file); |
| 87 | + |
| 88 | + if format_path.as_path().exists() { |
| 89 | + let mut new_filename = path.to_str().unwrap().to_string(); |
| 90 | + let re = Regex::new(r"[\\:/]").unwrap(); |
| 91 | + new_filename = re.replace_all(&new_filename, "_").to_string(); |
| 92 | + new_filename.push_str(format_ext); |
| 93 | + format_path.pop(); |
| 94 | + format_path.push(new_filename); |
| 95 | + } |
| 96 | + |
| 97 | + let mut format_file = File::create(format_path)?; |
| 98 | + match output_format { |
| 99 | + Format::Cbor => serde_cbor::to_writer(format_file, &space) |
| 100 | + .map_err(|e| Error::new(ErrorKind::Other, e.to_string())), |
| 101 | + Format::Json => { |
| 102 | + if pretty { |
| 103 | + serde_json::to_writer_pretty(format_file, &space) |
| 104 | + .map_err(|e| Error::new(ErrorKind::Other, e.to_string())) |
| 105 | + } else { |
| 106 | + serde_json::to_writer(format_file, &space) |
| 107 | + .map_err(|e| Error::new(ErrorKind::Other, e.to_string())) |
| 108 | + } |
| 109 | + } |
| 110 | + Format::Toml => { |
| 111 | + let toml_data = if pretty { |
| 112 | + toml::to_string_pretty(&space).unwrap() |
| 113 | + } else { |
| 114 | + toml::to_string(&space).unwrap() |
| 115 | + }; |
| 116 | + format_file.write_all(toml_data.as_bytes()) |
| 117 | + } |
| 118 | + Format::Yaml => serde_yaml::to_writer(format_file, &space) |
| 119 | + .map_err(|e| Error::new(ErrorKind::Other, e.to_string())), |
| 120 | + } |
| 121 | + } |
| 122 | +} |
0 commit comments