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'
|
# 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
|
||||||
|
|
10
README.md
10
README.md
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
})
|
})
|
||||||
|
|
|
@ -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: §ions.into_iter().map(String::from).collect::<Vec<_>>(),
|
sections: §ions.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")]
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue