implement Display and Error traits for our error objects

This commit is contained in:
Dmitriy Pleshevskiy 2022-07-31 00:54:38 +03:00
parent 2a6eab45c5
commit 832de949b6
Signed by: pleshevskiy
GPG key ID: 1B59187B161C0215
4 changed files with 61 additions and 27 deletions

View file

@ -30,6 +30,9 @@ GRAPHQL_PLAYGROUND=1
# VITE_SITE_URL='https://www.develop.staging.example.com' # VITE_SITE_URL='https://www.develop.staging.example.com'
# CYPRESS_API_BASE_URL='https://app.develop.staging.example.com/api' # CYPRESS_API_BASE_URL='https://app.develop.staging.example.com/api'
### debug
# DEBUG_VAR=1
### debug:on,local ### debug:on,local
# DEBUG=1 # DEBUG=1
### debug:off,staging ### debug:off,staging

View file

@ -25,10 +25,16 @@ vnetod local debug # enable local and debug sections
vnetod # disable all sections vnetod # disable all sections
``` ```
Namespaces You can also use variables from namespaces
```sh ```sh
vnetod db:local debug:on vnetod db:staging debug:off
```
You can switch between states and overwrite from namespaces at the same time.
```sh
vnetod local db:staging debug:off
``` ```
# License # License

View file

@ -1,5 +1,5 @@
use crate::{cli::Args, domain}; use crate::{cli::Args, domain};
use std::{cell::RefCell, fs::File}; use std::fs::File;
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
@ -7,13 +7,24 @@ pub enum Error {
Switch(domain::switch::Error), Switch(domain::switch::Error),
} }
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::OpenFile => f.write_str("Cannot open file"),
Error::Switch(inner) => write!(f, "Cannot switch between states: {}", inner),
}
}
}
impl std::error::Error for Error {}
pub fn execute(args: &Args) -> Result<(), Error> { pub fn execute(args: &Args) -> Result<(), Error> {
let reader = File::open(&args.file).map_err(|_| Error::OpenFile)?; let content = std::fs::read_to_string(&args.file).map_err(|_| Error::OpenFile)?;
let writer = let writer =
File::create(args.output.as_ref().unwrap_or(&args.file)).map_err(|_| Error::OpenFile)?; File::create(args.output.as_ref().unwrap_or(&args.file)).map_err(|_| Error::OpenFile)?;
domain::switch::execute(domain::switch::Request { domain::switch::execute(domain::switch::Request {
reader: RefCell::new(reader), content: &content,
writer, writer,
sections: &args.sections, sections: &args.sections,
}) })

View file

@ -1,35 +1,35 @@
use std::cell::RefCell; use std::io::{BufWriter, Write};
use std::io::{BufWriter, Read, Write};
use super::Section; use super::Section;
#[derive(Debug)] #[derive(Debug)]
pub enum Error { pub enum Error {
ReadData,
WriteData, WriteData,
} }
pub struct Request<'args, R, W> impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::WriteData => f.write_str("Cannot write data"),
}
}
}
impl std::error::Error for Error {}
pub struct Request<'args, W>
where where
R: Read,
W: Write, W: Write,
{ {
pub reader: RefCell<R>, pub content: &'args str,
pub writer: W, pub writer: W,
pub sections: &'args [String], pub sections: &'args [String],
} }
pub fn execute<R, W>(req: Request<R, W>) -> Result<(), Error> pub fn execute<W>(req: Request<W>) -> Result<(), Error>
where where
R: Read,
W: Write, W: Write,
{ {
let mut content = String::new();
req.reader
.borrow_mut()
.read_to_string(&mut content)
.map_err(|_| Error::ReadData)?;
let mut writer = BufWriter::new(req.writer); let mut writer = BufWriter::new(req.writer);
let choose_sections = req let choose_sections = req
@ -40,7 +40,7 @@ where
let mut current_sections: Option<Vec<Section>> = None; let mut current_sections: Option<Vec<Section>> = None;
for line in content.split_inclusive('\n') { for line in req.content.split_inclusive('\n') {
let new_line = if is_section_end(line) { let new_line = if is_section_end(line) {
current_sections = None; current_sections = None;
line.to_string() line.to_string()
@ -102,31 +102,29 @@ fn should_enable_variable(choose_sections: &[Section], current_sections: &[Secti
fn should_disable_variable(choose_sections: &[Section], current_sections: &[Section]) -> bool { fn should_disable_variable(choose_sections: &[Section], current_sections: &[Section]) -> bool {
choose_sections.is_empty() choose_sections.is_empty()
|| choose_sections.iter().any(|s| s.namespace.is_none()) || choose_sections.iter().any(|s| s.namespace.is_none())
|| !choose_sections || choose_sections
.iter() .iter()
.filter(|s| s.namespace.is_some()) .filter(|s| s.namespace.is_some())
.any(|s| { .any(|s| {
current_sections current_sections
.iter() .iter()
.any(|s2| s.namespace == s2.namespace) .any(|s2| s.namespace == s2.namespace && s.name != s2.name)
}) })
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use std::cell::RefCell;
use std::io::Cursor; use std::io::Cursor;
const BASE_ENV: &str = include_str!("../../test_data/base_env"); const BASE_ENV: &str = include_str!("../../test_data/base_env");
fn make_test(input: &str, expected_output: &str, sections: Vec<&str>) { fn make_test(input: &str, expected_output: &str, sections: Vec<&str>) {
let reader = RefCell::new(Cursor::new(input));
let mut output_data = vec![]; let mut output_data = vec![];
let writer = Cursor::new(&mut output_data); let writer = Cursor::new(&mut output_data);
match execute(Request { match execute(Request {
reader, content: input,
writer, writer,
sections: &sections.into_iter().map(String::from).collect::<Vec<_>>(), sections: &sections.into_iter().map(String::from).collect::<Vec<_>>(),
}) { }) {
@ -238,11 +236,27 @@ mod tests {
} }
#[test] #[test]
fn should_disable_variables() { fn should_not_disable_variables() {
assert!(should_disable_variable( assert!(!should_disable_variable(
&[Section::with_namespace("debug", "on")], &[Section::with_namespace("debug", "on")],
&[Section::new("local")] &[Section::new("local")]
)); ));
} }
#[test]
fn should_disable_variables() {
assert!(should_disable_variable(
&[Section::new("local")],
&[Section::with_namespace("debug", "off")]
));
assert!(should_disable_variable(
&[],
&[Section::with_namespace("debug", "off")]
));
assert!(should_disable_variable(
&[Section::with_namespace("debug", "on")],
&[Section::with_namespace("debug", "off")]
));
}
} }
} }