implement Display and Error traits for our error objects
This commit is contained in:
parent
2a6eab45c5
commit
832de949b6
4 changed files with 61 additions and 27 deletions
|
@ -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
|
||||
|
|
10
README.md
10
README.md
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
|
|
|
@ -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: §ions.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")]
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue