feat: add result to getenv functions
BREAKING_CHANGES: get env function returns result instead panic
This commit is contained in:
parent
ee988af061
commit
e1cbcb7696
10 changed files with 195 additions and 65 deletions
20
README.md
20
README.md
|
@ -1,7 +1,7 @@
|
||||||
# itconfig
|
# itconfig
|
||||||
[![Build Status](https://travis-ci.org/icetemple/itconfig-rs.svg?branch=master)](https://travis-ci.org/icetemple/itconfig-rs)
|
[![Build Status](https://travis-ci.org/icetemple/itconfig-rs.svg?branch=master)](https://travis-ci.org/icetemple/itconfig-rs)
|
||||||
[![Documentation](https://docs.rs/itconfig/badge.svg)](https://docs.rs/itconfig)
|
[![Documentation](https://docs.rs/itconfig/badge.svg)](https://docs.rs/itconfig)
|
||||||
[![Crates.io](https://img.shields.io/badge/crates.io-v0.9.0-orange.svg?longCache=true)](https://crates.io/crates/itconfig)
|
[![Crates.io](https://img.shields.io/badge/crates.io-v0.10.0-orange.svg?longCache=true)](https://crates.io/crates/itconfig)
|
||||||
[![Join the chat at https://gitter.im/icetemple/itconfig-rs](https://badges.gitter.im/icetemple/itconfig-rs.svg)](https://gitter.im/icetemple/itconfig-rs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[![Join the chat at https://gitter.im/icetemple/itconfig-rs](https://badges.gitter.im/icetemple/itconfig-rs.svg)](https://gitter.im/icetemple/itconfig-rs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
|
|
||||||
Easy build a configs from environment variables and use it in globally.
|
Easy build a configs from environment variables and use it in globally.
|
||||||
|
@ -75,6 +75,24 @@ fn main () {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Macro is an optional feature, enabled by default. You can install itconfig without default
|
||||||
|
features and use this lib as shown below
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use itconfig::*;
|
||||||
|
use std::env;
|
||||||
|
// use dotenv::dotenv;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
env::set_var("DATABASE_URL", "postgres://127.0.0.1:5432/test");
|
||||||
|
|
||||||
|
let database_url = get_env::<String>("DATABASE_URL").unwrap();
|
||||||
|
let new_profile: bool = get_env_or_default("FEATURE_NEW_PROFILE", false);
|
||||||
|
let articles_per_page: u32 = get_env_or_set_default("ARTICLES_PER_PAGE", 10);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Running tests
|
## Running tests
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
|
@ -5,7 +5,6 @@ extern crate rocket;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate itconfig;
|
extern crate itconfig;
|
||||||
|
|
||||||
use rocket::config::{Config, Environment};
|
|
||||||
|
|
||||||
config! {
|
config! {
|
||||||
ROCKET {
|
ROCKET {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "itconfig"
|
name = "itconfig"
|
||||||
version = "0.9.0"
|
version = "0.10.0"
|
||||||
authors = ["Dmitriy Pleshevskiy <dmitriy@ideascup.me>"]
|
authors = ["Dmitriy Pleshevskiy <dmitriy@ideascup.me>"]
|
||||||
description = "Easy build a configs from environment variables and use it in globally."
|
description = "Easy build a configs from environment variables and use it in globally."
|
||||||
categories = ["config", "web-programming"]
|
categories = ["config", "web-programming"]
|
||||||
|
@ -19,6 +19,7 @@ travis-ci = { repository = "icetemple/itconfig-rs" }
|
||||||
maintenance = { status = "actively-developed" }
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
failure = { version = "0.1.6", features = ["derive"]}
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ['macro']
|
default = ['macro']
|
||||||
|
|
|
@ -63,6 +63,24 @@ fn main () {
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
Macro is an optional feature, enabled by default. You can install itconfig without default
|
||||||
|
features and use this lib as shown below
|
||||||
|
|
||||||
|
```rust
|
||||||
|
use itconfig::*;
|
||||||
|
use std::env;
|
||||||
|
// use dotenv::dotenv;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
env::set_var("DATABASE_URL", "postgres://127.0.0.1:5432/test");
|
||||||
|
|
||||||
|
let database_url = get_env::<String>("DATABASE_URL").unwrap();
|
||||||
|
let new_profile: bool = get_env_or_default("FEATURE_NEW_PROFILE", false);
|
||||||
|
let articles_per_page: u32 = get_env_or_set_default("ARTICLES_PER_PAGE", 10);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Roadmap
|
## Roadmap
|
||||||
|
|
||||||
* [x] Add namespace for variables
|
* [x] Add namespace for variables
|
||||||
|
|
10
itconfig/src/enverr.rs
Normal file
10
itconfig/src/enverr.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
use failure::Fail;
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Debug, Fail, PartialEq)]
|
||||||
|
pub enum EnvError {
|
||||||
|
#[fail(display = r#"Environment variable "{}" is missing"#, env_name)]
|
||||||
|
MissingVariable { env_name: String },
|
||||||
|
#[fail(display = r#"Failed to parse environment variable "{}""#, env_name)]
|
||||||
|
FailedToParse { env_name: String },
|
||||||
|
}
|
|
@ -1,26 +1,25 @@
|
||||||
use std::env;
|
use std::env;
|
||||||
use crate::envstr::{EnvString, FromEnvString, ToEnvString};
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
/// This function is similar as `get_env`, but it unwraps result with panic on error.
|
||||||
macro_rules! env_panic {
|
|
||||||
(MissingVariable, $env_name:expr) => {
|
|
||||||
panic!(r#"Environment variable "{}" is missing"#, $env_name)
|
|
||||||
};
|
|
||||||
(FailedToParse, $env_name:expr) => {
|
|
||||||
panic!(r#"Failed to parse environment variable "{}""#, $env_name)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Try to read environment variable and parse to expected type. You may to put to argument
|
|
||||||
/// any type with `FromEnvString` trait.
|
|
||||||
///
|
///
|
||||||
/// Panics
|
/// Panics
|
||||||
/// ------
|
/// ------
|
||||||
/// Application will panic if environment variable is missing or cannot parse variable to
|
/// Application will panic if environment variable is missing or cannot parse variable to
|
||||||
/// expected type
|
/// expected type
|
||||||
///
|
///
|
||||||
|
pub fn get_env_or_panic<T>(env_name: &str) -> T
|
||||||
|
where
|
||||||
|
T: FromEnvString
|
||||||
|
{
|
||||||
|
get_env(env_name).unwrap_or_else(make_panic)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Try to read environment variable and parse to expected type. You may to put to argument
|
||||||
|
/// any type with `FromEnvString` trait.
|
||||||
|
///
|
||||||
/// Example
|
/// Example
|
||||||
/// -------
|
/// -------
|
||||||
///
|
///
|
||||||
|
@ -32,21 +31,23 @@ macro_rules! env_panic {
|
||||||
/// fn main () {
|
/// fn main () {
|
||||||
/// env::set_var("DEBUG", "true");
|
/// env::set_var("DEBUG", "true");
|
||||||
///
|
///
|
||||||
/// let result: bool = get_env("DEBUG");
|
/// let result: bool = get_env("DEBUG").unwrap();
|
||||||
///
|
///
|
||||||
/// assert_eq!(result, true);
|
/// assert_eq!(result, true);
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
pub fn get_env<T>(env_name: &str) -> T
|
pub fn get_env<T>(env_name: &str) -> Result<T, EnvError>
|
||||||
where
|
where
|
||||||
T: FromEnvString
|
T: FromEnvString
|
||||||
{
|
{
|
||||||
get_env_or(env_name, || env_panic!(MissingVariable, env_name))
|
get_env_or(env_name, |_| {
|
||||||
|
Err(EnvError::MissingVariable { env_name: env_name.to_string() })
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// This function is similar as `get_env` but more safely. You can pass default value for
|
/// This function is similar as `get_env_or_panic`, but you can pass default value for
|
||||||
/// environment variable with `ToEnvString` trait.
|
/// environment variable with `ToEnvString` trait.
|
||||||
///
|
///
|
||||||
/// Panics
|
/// Panics
|
||||||
|
@ -72,12 +73,13 @@ pub fn get_env_or_default<T, D>(env_name: &str, default: D) -> T
|
||||||
T: FromEnvString,
|
T: FromEnvString,
|
||||||
D: ToEnvString,
|
D: ToEnvString,
|
||||||
{
|
{
|
||||||
get_env_or(env_name, || default.to_env_string())
|
get_env_or(env_name, |_| Ok(default.to_env_string()))
|
||||||
|
.unwrap_or_else(make_panic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// This function is similar as `get_env_or_default` but if env variable is missed, will set
|
/// This function is similar as `get_env_or_default`, but the default value will be set to environment
|
||||||
/// default value to environment variable.
|
/// variable, if env variable is missed.
|
||||||
///
|
///
|
||||||
/// Panics
|
/// Panics
|
||||||
/// ------
|
/// ------
|
||||||
|
@ -105,37 +107,42 @@ pub fn get_env_or_set_default<T, D>(env_name: &str, default: D) -> T
|
||||||
T: FromEnvString,
|
T: FromEnvString,
|
||||||
D: ToEnvString,
|
D: ToEnvString,
|
||||||
{
|
{
|
||||||
get_env_or(env_name, || {
|
get_env_or(env_name, |_| {
|
||||||
let val = default.to_env_string();
|
let val = default.to_env_string();
|
||||||
env::set_var(env_name, val.as_str());
|
env::set_var(env_name, val.as_str());
|
||||||
val
|
Ok(val)
|
||||||
})
|
}).unwrap_or_else(make_panic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// This function returns env variable as `EnvString` structure. You can pass callback for custom
|
/// This function returns env variable as `EnvString` structure. You can pass callback for custom
|
||||||
/// default expression. Callback should return `EnvString` value or `panic!`
|
/// default expression. Callback should return `EnvString` value or `EnvError`
|
||||||
pub fn get_env_or<T, F>(env_name: &str, cb: F) -> T
|
pub fn get_env_or<T, F>(env_name: &str, cb: F) -> Result<T, EnvError>
|
||||||
where
|
where
|
||||||
T: FromEnvString,
|
T: FromEnvString,
|
||||||
F: FnOnce() -> EnvString
|
F: FnOnce(env::VarError) -> Result<EnvString, EnvError>
|
||||||
{
|
{
|
||||||
let env_str = env::var(env_name)
|
env::var(env_name)
|
||||||
.map(|s| s.to_env_string())
|
.map(|s| s.to_env_string())
|
||||||
.unwrap_or_else(|_| cb());
|
.or_else(cb)
|
||||||
|
.and_then(|env_str| {
|
||||||
parse_env_variable(env_name, env_str)
|
parse_env_variable(env_name, env_str)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
fn parse_env_variable<T>(env_name: &str, env_str: EnvString) -> T
|
fn parse_env_variable<T>(env_name: &str, env_str: EnvString) -> Result<T, EnvError>
|
||||||
where
|
where
|
||||||
T: FromEnvString
|
T: FromEnvString
|
||||||
{
|
{
|
||||||
env_str
|
env_str
|
||||||
.parse::<T>()
|
.parse::<T>()
|
||||||
.unwrap_or_else(|_| env_panic!(FailedToParse, env_name))
|
.map_err(|_| EnvError::FailedToParse { env_name: env_name.to_string() })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
fn make_panic<T>(e: EnvError) -> T {
|
||||||
|
panic!("{}", e)
|
||||||
|
}
|
||||||
|
|
|
@ -1,15 +1,109 @@
|
||||||
|
//! # itconfig
|
||||||
|
//!
|
||||||
|
//! Simple configuration with macro for rust application.
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
//! ## Motivation
|
||||||
|
//!
|
||||||
|
//! I began to use rust with web programming experience where environment variables are widely used
|
||||||
|
//! and often there are more then 50 of them. First I looked at already created libraries.
|
||||||
|
//! But there it's necessary to initialise structure that needs to be moved to each function
|
||||||
|
//! where you need variable. It uses little bit memory, but configuration lifetime is as long
|
||||||
|
//! as application lifetime. Because of it I decided to create my own library.
|
||||||
|
//!
|
||||||
|
//!
|
||||||
|
//! ## Example usage
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! #[macro_use] extern crate itconfig;
|
||||||
|
//! use std::env;
|
||||||
|
//! // use dotenv::dotenv;
|
||||||
|
//!
|
||||||
|
//! config! {
|
||||||
|
//! DEBUG: bool => true,
|
||||||
|
//! HOST: String => "127.0.0.1",
|
||||||
|
//!
|
||||||
|
//! DATABASE_URL < (
|
||||||
|
//! "postgres://",
|
||||||
|
//! POSTGRES_USERNAME => "user",
|
||||||
|
//! ":",
|
||||||
|
//! POSTGRES_PASSWORD => "pass",
|
||||||
|
//! "@",
|
||||||
|
//! POSTGRES_HOST => "localhost:5432",
|
||||||
|
//! "/",
|
||||||
|
//! POSTGRES_DB => "test",
|
||||||
|
//! ),
|
||||||
|
//!
|
||||||
|
//! APP {
|
||||||
|
//! ARTICLE {
|
||||||
|
//! PER_PAGE: u32 => 15,
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! #[cfg(feature = "companies")]
|
||||||
|
//! COMPANY {
|
||||||
|
//! #[env_name = "INSTITUTIONS_PER_PAGE"]
|
||||||
|
//! PER_PAGE: u32 => 15,
|
||||||
|
//! }
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! FEATURE {
|
||||||
|
//! NEW_MENU: bool => false,
|
||||||
|
//!
|
||||||
|
//! COMPANY {
|
||||||
|
//! PROFILE: bool => false,
|
||||||
|
//! }
|
||||||
|
//! }
|
||||||
|
//! }
|
||||||
|
//!
|
||||||
|
//! fn main () {
|
||||||
|
//! // dotenv().ok();
|
||||||
|
//! env::set_var("FEATURE_NEW_MENU", "t");
|
||||||
|
//!
|
||||||
|
//! cfg::init();
|
||||||
|
//! assert_eq!(cfg::HOST(), String::from("127.0.0.1"));
|
||||||
|
//! assert_eq!(cfg::DATABASE_URL(), String::from("postgres://user:pass@localhost:5432/test"));
|
||||||
|
//! assert_eq!(cfg::APP::ARTICLE::PER_PAGE(), 15);
|
||||||
|
//! assert_eq!(cfg::FEATURE::NEW_MENU(), true);
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! Macro is an optional feature, enabled by default. You can install itconfig without default
|
||||||
|
//! features and use this lib as shown below
|
||||||
|
//!
|
||||||
|
//! ```rust
|
||||||
|
//! use itconfig::*;
|
||||||
|
//! use std::env;
|
||||||
|
//! // use dotenv::dotenv;
|
||||||
|
//!
|
||||||
|
//! fn main() {
|
||||||
|
//! env::set_var("DATABASE_URL", "postgres://127.0.0.1:5432/test");
|
||||||
|
//!
|
||||||
|
//! let database_url = get_env::<String>("DATABASE_URL").unwrap();
|
||||||
|
//! let new_profile: bool = get_env_or_default("FEATURE_NEW_PROFILE", false);
|
||||||
|
//! let articles_per_page: u32 = get_env_or_set_default("ARTICLES_PER_PAGE", 10);
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
|
||||||
|
|
||||||
// Rustc lints.
|
// Rustc lints.
|
||||||
#![deny(unused_imports)]
|
#![deny(unused_imports)]
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate failure;
|
||||||
|
|
||||||
|
mod enverr;
|
||||||
mod getenv;
|
mod getenv;
|
||||||
pub mod envstr;
|
pub mod envstr;
|
||||||
|
|
||||||
pub use self::getenv::*;
|
pub use self::getenv::*;
|
||||||
|
pub use self::enverr::*;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use crate::envstr::*;
|
pub use crate::envstr::*;
|
||||||
|
pub use crate::enverr::*;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
|
||||||
|
/// ### _This API requires the following crate features to be activated: `macro`_
|
||||||
|
///
|
||||||
/// Creates new public mod with function fo get each environment variable of mapping.
|
/// Creates new public mod with function fo get each environment variable of mapping.
|
||||||
///
|
///
|
||||||
/// All variables are required and program will panic if some variables haven't value, but you
|
/// All variables are required and program will panic if some variables haven't value, but you
|
||||||
|
@ -589,9 +592,7 @@ macro_rules! __itconfig_concat_param {
|
||||||
|
|
||||||
// Find env parameter without default value
|
// Find env parameter without default value
|
||||||
($env_name:ident) => (
|
($env_name:ident) => (
|
||||||
itconfig::get_env(
|
itconfig::get_env_or_panic(stringify!($env_name).to_uppercase().as_str())
|
||||||
stringify!($env_name).to_uppercase().as_str()
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Find string parameter
|
// Find string parameter
|
||||||
|
@ -627,24 +628,6 @@ macro_rules! __itconfig_variable {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add method for concatenated variable
|
|
||||||
// (
|
|
||||||
// meta = [$(#$meta:tt,)*],
|
|
||||||
// concat = [$($concat:expr,)+],
|
|
||||||
// name = $name:ident,
|
|
||||||
// env_prefix = $env_prefix:expr,
|
|
||||||
// env_name = $env_name:expr,
|
|
||||||
// ty = $ty:ty,
|
|
||||||
// $($args:tt)*
|
|
||||||
// ) => {
|
|
||||||
// $(#$meta)*
|
|
||||||
// pub fn $name() -> $ty {
|
|
||||||
// let value_parts: Vec<String> = vec!($($concat),+);
|
|
||||||
// let value = value_parts.join("");
|
|
||||||
// __itconfig_variable_helper!(@setenv $env_name, value)
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
|
|
||||||
// Add method for env variable
|
// Add method for env variable
|
||||||
(
|
(
|
||||||
meta = [$(#$meta:tt,)*],
|
meta = [$(#$meta:tt,)*],
|
||||||
|
@ -666,6 +649,7 @@ macro_rules! __itconfig_variable {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Concatenate function body
|
||||||
(
|
(
|
||||||
@inner
|
@inner
|
||||||
concat = [$($concat:expr,)+],
|
concat = [$($concat:expr,)+],
|
||||||
|
@ -678,14 +662,16 @@ macro_rules! __itconfig_variable {
|
||||||
value
|
value
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Env without default
|
||||||
(
|
(
|
||||||
@inner
|
@inner
|
||||||
concat = [],
|
concat = [],
|
||||||
env_name = $env_name:expr,
|
env_name = $env_name:expr,
|
||||||
) => (
|
) => (
|
||||||
itconfig::get_env($env_name.to_string().as_str())
|
itconfig::get_env_or_panic($env_name.to_string().as_str())
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Env with default
|
||||||
(
|
(
|
||||||
@inner
|
@inner
|
||||||
concat = [],
|
concat = [],
|
||||||
|
|
|
@ -4,20 +4,20 @@ use itconfig::*;
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "Environment variable \"TEST_CASE_1\" is missing")]
|
#[should_panic(expected = "Environment variable \"TEST_CASE_1\" is missing")]
|
||||||
fn missing_env_variable() {
|
fn missing_env_variable() {
|
||||||
get_env::<String>("TEST_CASE_1");
|
get_env_or_panic::<String>("TEST_CASE_1");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[should_panic(expected = "Failed to parse environment variable \"TEST_CASE_2\"")]
|
#[should_panic(expected = "Failed to parse environment variable \"TEST_CASE_2\"")]
|
||||||
fn cannot_parse_env_variable() {
|
fn cannot_parse_env_variable() {
|
||||||
env::set_var("TEST_CASE_2", "30r");
|
env::set_var("TEST_CASE_2", "30r");
|
||||||
get_env::<u32>("TEST_CASE_2");
|
get_env_or_panic::<u32>("TEST_CASE_2");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn get_env_successfully() {
|
fn get_env_successfully() {
|
||||||
env::set_var("TEST_CASE_3", "30");
|
env::set_var("TEST_CASE_3", "30");
|
||||||
let a: u32 = get_env("TEST_CASE_3");
|
let a = get_env::<u32>("TEST_CASE_3").unwrap();
|
||||||
|
|
||||||
assert_eq!(a, 30);
|
assert_eq!(a, 30);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,9 +5,6 @@ use itconfig::*;
|
||||||
fn missing_env_variable() {
|
fn missing_env_variable() {
|
||||||
let flag: bool = get_env_or_default("DEFAULT_TEST_CASE_1", "true");
|
let flag: bool = get_env_or_default("DEFAULT_TEST_CASE_1", "true");
|
||||||
assert_eq!(flag, true);
|
assert_eq!(flag, true);
|
||||||
|
|
||||||
// let var: String = env::var("DEFAULT_TEST_CASE_1").unwrap();
|
|
||||||
// assert_eq!(var, "true");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Reference in a new issue