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'
# CYPRESS_API_BASE_URL='https://app.develop.staging.example.com/api'
### debug
# DEBUG_VAR=1
### debug:on,local
# DEBUG=1
### debug:off,staging

View File

@ -25,10 +25,16 @@ vnetod local debug # enable local and debug sections
vnetod # disable all sections
```
Namespaces
You can also use variables from namespaces
```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

View File

@ -1,5 +1,5 @@
use crate::{cli::Args, domain};
use std::{cell::RefCell, fs::File};
use std::fs::File;
#[derive(Debug)]
pub enum Error {
@ -7,13 +7,24 @@ pub enum 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> {
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 =
File::create(args.output.as_ref().unwrap_or(&args.file)).map_err(|_| Error::OpenFile)?;
domain::switch::execute(domain::switch::Request {
reader: RefCell::new(reader),
content: &content,
writer,
sections: &args.sections,
})

View File

@ -1,35 +1,35 @@
use std::cell::RefCell;
use std::io::{BufWriter, Read, Write};
use std::io::{BufWriter, Write};
use super::Section;
#[derive(Debug)]
pub enum Error {
ReadData,
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
R: Read,
W: Write,
{
pub reader: RefCell<R>,
pub content: &'args str,
pub writer: W,
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
R: Read,
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 choose_sections = req
@ -40,7 +40,7 @@ where
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) {
current_sections = None;
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 {
choose_sections.is_empty()
|| choose_sections.iter().any(|s| s.namespace.is_none())
|| !choose_sections
|| choose_sections
.iter()
.filter(|s| s.namespace.is_some())
.any(|s| {
current_sections
.iter()
.any(|s2| s.namespace == s2.namespace)
.any(|s2| s.namespace == s2.namespace && s.name != s2.name)
})
}
#[cfg(test)]
mod tests {
use super::*;
use std::cell::RefCell;
use std::io::Cursor;
const BASE_ENV: &str = include_str!("../../test_data/base_env");
fn make_test(input: &str, expected_output: &str, sections: Vec<&str>) {
let reader = RefCell::new(Cursor::new(input));
let mut output_data = vec![];
let writer = Cursor::new(&mut output_data);
match execute(Request {
reader,
content: input,
writer,
sections: &sections.into_iter().map(String::from).collect::<Vec<_>>(),
}) {
@ -238,11 +236,27 @@ mod tests {
}
#[test]
fn should_disable_variables() {
assert!(should_disable_variable(
fn should_not_disable_variables() {
assert!(!should_disable_variable(
&[Section::with_namespace("debug", "on")],
&[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")]
));
}
}
}