diff --git a/.github/release.yml b/.github/release.yml index d5d53f6..5c2a611 100644 --- a/.github/release.yml +++ b/.github/release.yml @@ -1,28 +1,28 @@ changelog: categories: - - title: ๐Ÿ’ฃ Breaking Changes - labels: - - breaking-change - - title: ๐Ÿš€ Features - labels: - - feature - - title: ๐Ÿ› Bug Fixes - labels: - - bug - - title: ๐Ÿ“ Documentation - labels: - - doc - - title: ๐Ÿงช Tests - labels: - - test - - title: ๐Ÿ“ฆ Dependencies - labels: - - dependencies - - title: ๐Ÿ› ๏ธ Build - labels: - - build - - title: ๐Ÿ“Œ Chore - labels: - - chore + - title: ๐Ÿ’ฃ Breaking Changes + labels: + - breaking-change + - title: ๐Ÿš€ Features + labels: + - feature + - title: ๐Ÿ› Bug Fixes + labels: + - bug + - title: ๐Ÿ“ Documentation + labels: + - doc + - title: ๐Ÿงช Tests + labels: + - test + - title: ๐Ÿ“ฆ Dependencies + labels: + - dependencies + - title: ๐Ÿ› ๏ธ Build + labels: + - build + - title: ๐Ÿ“Œ Chore + labels: + - chore exclude: labels: [ci] diff --git a/.github/workflows/cache.yml b/.github/workflows/cache.yml index b32a0fd..a4838e8 100644 --- a/.github/workflows/cache.yml +++ b/.github/workflows/cache.yml @@ -6,38 +6,38 @@ concurrency: on: push: - branches: [main] - paths: - - "**.rs" - - Cargo.toml + branches: [main] + paths: + - '**.rs' + - Cargo.toml jobs: cache: name: Cache runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 - - name: Set up Rust - id: rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable + - name: Set up Rust + id: rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable - - name: Restore cache - uses: actions/cache@v3 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ runner.os }}-${{ steps.rust.outputs.rustc_hash }}-${{ hashFiles('Cargo.toml') }} + - name: Restore cache + uses: actions/cache@v3 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-${{ steps.rust.outputs.rustc_hash }}-${{ hashFiles('Cargo.toml') }} - - name: Build (debug) - uses: actions-rs/cargo@v1 - with: - args: --all-features - command: build + - name: Build (debug) + uses: actions-rs/cargo@v1 + with: + args: --all-features + command: build diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 0e755fa..003c2e6 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -8,30 +8,30 @@ on: pull_request: branches: [main] paths: - - .github/workflows/quality.yml - - "**.rs" - - Cargo.toml + - .github/workflows/quality.yml + - '**.rs' + - Cargo.toml jobs: commit: name: Commit runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v3 - with: - fetch-depth: 2 + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 2 - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: 18 + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: 18 - - name: Install commitlint - run: npm install --global @commitlint/{cli,config-conventional} + - name: Install commitlint + run: npm install --global @commitlint/{cli,config-conventional} - - name: Lint - run: commitlint --from=HEAD~1 + - name: Lint + run: commitlint --from=HEAD~1 quality: name: Quality @@ -44,54 +44,54 @@ jobs: POSTGRES_PASSWORD: mockable POSTGRES_USER: mockable ports: - - 5432:5432 + - 5432:5432 steps: - - name: Checkout - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 - - name: Set up Rust - id: rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: clippy,rustfmt + - name: Set up Rust + id: rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + components: clippy,rustfmt - - name: Restore cache - uses: actions/cache@v3 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ runner.os }}-${{ steps.rust.outputs.rustc_hash }}-${{ hashFiles('Cargo.toml') }} + - name: Restore cache + uses: actions/cache@v3 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-${{ steps.rust.outputs.rustc_hash }}-${{ hashFiles('Cargo.toml') }} - - name: Check format - uses: actions-rs/cargo@v1 - with: - args: --check - command: fmt + - name: Check format + uses: actions-rs/cargo@v1 + with: + args: --check + command: fmt - - name: Lint - uses: actions-rs/cargo@v1 - with: - args: --all-features --tests -- -D warnings - command: clippy + - name: Lint + uses: actions-rs/cargo@v1 + with: + args: --all-features --tests -- -D warnings + command: clippy - - name: Initialize database - env: - PGPASSWORD: mockable - run: psql -h 127.0.0.1 -U mockable -d mockable -f ./docker-compose/db/init.sql + - name: Initialize database + env: + PGPASSWORD: mockable + run: psql -h 127.0.0.1 -U mockable -d mockable -f ./docker-compose/db/init.sql - - name: Test - uses: actions-rs/cargo@v1 - with: - args: --all-features - command: test + - name: Test + uses: actions-rs/cargo@v1 + with: + args: --all-features + command: test - - name: Test examples - uses: actions-rs/cargo@v1 - with: - args: --all-features --examples - command: test + - name: Test examples + uses: actions-rs/cargo@v1 + with: + args: --all-features --examples + command: test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 64c5a16..ada34f8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,42 +5,42 @@ permissions: on: push: - tags: ["*"] + tags: ['*'] jobs: release: name: Release runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 - - name: Set up Rust - id: rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable + - name: Set up Rust + id: rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable - - name: Restore cache - uses: actions/cache@v3 - with: - path: | - ~/.cargo/bin/ - ~/.cargo/registry/index/ - ~/.cargo/registry/cache/ - ~/.cargo/git/db/ - target/ - key: ${{ runner.os }}-${{ steps.rust.outputs.rustc_hash }}-${{ hashFiles('Cargo.toml') }} + - name: Restore cache + uses: actions/cache@v3 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target/ + key: ${{ runner.os }}-${{ steps.rust.outputs.rustc_hash }}-${{ hashFiles('Cargo.toml') }} - - name: Publish - uses: actions-rs/cargo@v1 - env: - CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} - with: - args: --all-features - command: publish + - name: Publish + uses: actions-rs/cargo@v1 + env: + CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} + with: + args: --all-features + command: publish - - name: Create release - uses: softprops/action-gh-release@v1 - with: - generate_release_notes: true + - name: Create release + uses: softprops/action-gh-release@v1 + with: + generate_release_notes: true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 107d032..99ef451 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,15 +1,25 @@ repos: - - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 - hooks: - - id: trailing-whitespace - exclude: .rs$ - - id: end-of-file-fixer - exclude: .rs$ - - repo: https://github.com/doublify/pre-commit-rust - rev: v1.0 - hooks: - - id: fmt - - id: cargo-check - - id: clippy - args: ["--tests", "--", "-D", "warnings"] +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 + hooks: + - id: check-json + - id: check-yaml + - id: trailing-whitespace + exclude: .rs$ + - id: end-of-file-fixer + exclude: .rs$ +- repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks + rev: v2.11.0 + hooks: + - id: pretty-format-yaml + args: [--autofix] + - id: pretty-format-toml + args: [--autofix] +- repo: https://github.com/doublify/pre-commit-rust + rev: v1.0 + hooks: + - id: fmt + - id: cargo-check + args: [--all-features] + - id: clippy + args: [--all-features, --tests, --, -D, warnings] diff --git a/Cargo.toml b/Cargo.toml index 7c7385b..fdbd3a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,13 +1,17 @@ -[package] -name = "mockable" -version = "1.0.0" -authors = ["Guillaume Leroy "] -edition = "2021" -description = "Usefull components to make easier to mock your code" -documentation = "https://docs.rs/mockable" -license-file = "LICENSE" -keywords = ["mock", "mockable", "mocking", "test"] -categories = ["development-tools::testing"] +[dependencies] +async-trait = {version = "0.1", optional = true} +bytes = {version = "1.5", optional = true} +chrono = {version = "0.4", optional = true} +mockall = {version = "0.11", optional = true} +open = {version = "5.0", optional = true} +tokio = {version = "1.32", features = ["process"], optional = true} +tracing = "0.1" +uuid = {version = "0.8", features = ["v4"], optional = true} + +[dev-dependencies] +mockall = "0.11" +tokio = {version = "1.32", features = ["full"]} +tokio-test = "0.4" [features] browser = ["dep:open"] @@ -17,20 +21,16 @@ full = ["browser", "clock", "cmd", "uuid"] mock = ["dep:mockall"] uuid = ["dep:uuid"] -[dependencies] -async-trait = { version = "0.1", optional = true } -bytes = { version = "1.5", optional = true } -chrono = { version = "0.4", optional = true } -mockall = { version = "0.11", optional = true } -open = { version = "5.0", optional = true } -tokio = { version = "1.32", features = ["process"], optional = true} -tracing = "0.1" -uuid = { version = "0.8", features = ["v4"], optional = true } - -[dev-dependencies] -mockall = "0.11" -tokio = { version = "1.32", features = ["full"] } -tokio-test = "0.4" +[package] +authors = ["Guillaume Leroy "] +categories = ["development-tools::testing"] +description = "Usefull components to make easier to mock your code" +documentation = "https://docs.rs/mockable" +edition = "2021" +keywords = ["mock", "mockable", "mocking", "test"] +license-file = "LICENSE" +name = "mockable" +version = "1.0.0" [package.metadata.docs.rs] all-features = true diff --git a/docker-compose.yml b/docker-compose.yml index e3317a3..e0829f5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -version: "3" +version: '3' services: db: @@ -8,6 +8,6 @@ services: POSTGRES_PASSWORD: mockable POSTGRES_USER: mockable ports: - - 5432:5432 + - 5432:5432 volumes: - - ./docker-compose/db/init.sql:/docker-entrypoint-initdb.d/init.sql + - ./docker-compose/db/init.sql:/docker-entrypoint-initdb.d/init.sql diff --git a/src/env.rs b/src/env.rs index 5e4fb24..c84b222 100644 --- a/src/env.rs +++ b/src/env.rs @@ -1,59 +1,44 @@ use std::{ + char::ParseCharError, env::VarError, error::Error, ffi::OsString, - fmt::{Display, Formatter, Result as FmtResult}, - net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}, + net::{AddrParseError, IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}, num::{ NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, NonZeroU128, - NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, + NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, ParseFloatError, + ParseIntError, }, path::PathBuf, - str::FromStr, + str::{FromStr, ParseBoolError}, }; use tracing::{trace, warn}; // Macros -macro_rules! implementation { - ($ty:ident) => { - implementation!($ty, $ty); +macro_rules! parse_impl { + ($ty:ident, $err:ty) => { + parse_impl!($ty, $ty, $err); }; - ($ident:ident, $ty:ident) => { - fn $ident(&self, key: &str) -> Option> { - self.var(key) + ($ident:ident, $ty:ident, $err:ty) => { + fn $ident(&self, key: &str) -> Option> { + self.parse(key) } }; } -// Types - -pub type EnvParseResult = Result; - -// EnvParseError - -/// An error that can occur when parsing an environment variable. -#[derive(Debug)] -pub struct EnvParseError(Box); - -impl Display for EnvParseError { - fn fmt(&self, f: &mut Formatter) -> FmtResult { - write!(f, "{}", self.0) - } -} - -impl Error for EnvParseError { - fn source(&self) -> Option<&(dyn Error + 'static)> { - Some(self.0.as_ref()) - } -} +macro_rules! var_impl { + ($ty:ident) => { + var_impl!($ty, $ty); + }; -impl From> for EnvParseError { - fn from(err: Box) -> Self { - Self(err) - } + ($ident:ident, $ty:ident) => { + fn $ident(&self, key: &str) -> Option<$ty> { + self.var(key) + } + }; } // Env @@ -66,163 +51,163 @@ pub trait Env: Send + Sync { /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `bool`, an error is returned. - fn bool(&self, key: &str) -> Option>; + fn bool(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `char`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `char`, an error is returned. - fn char(&self, key: &str) -> Option>; + fn char(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `f32`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `f32`, an error is returned. - fn f32(&self, key: &str) -> Option>; + fn f32(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `f64`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `f64`, an error is returned. - fn f64(&self, key: &str) -> Option>; + fn f64(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `i8`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `i8`, an error is returned. - fn i8(&self, key: &str) -> Option>; + fn i8(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `i16`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `i16`, an error is returned. - fn i16(&self, key: &str) -> Option>; + fn i16(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `i32`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `i32`, an error is returned. - fn i32(&self, key: &str) -> Option>; + fn i32(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `i64`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `i64`, an error is returned. - fn i64(&self, key: &str) -> Option>; + fn i64(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `i128`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `i128`, an error is returned. - fn i128(&self, key: &str) -> Option>; + fn i128(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `IpAddr`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `IpAddr`, an error is returned. - fn ip_addr(&self, key: &str) -> Option>; + fn ip_addr(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `Ipv4Addr`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `Ipv4Addr`, an error is returned. - fn ipv4_addr(&self, key: &str) -> Option>; + fn ipv4_addr(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `Ipv6Addr`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `Ipv6Addr`, an error is returned. - fn ipv6_addr(&self, key: &str) -> Option>; + fn ipv6_addr(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `isize`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `isize`, an error is returned. - fn isize(&self, key: &str) -> Option>; + fn isize(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `NonZeroI8`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `NonZeroI8`, an error is returned. - fn non_zero_i8(&self, key: &str) -> Option>; + fn non_zero_i8(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `NonZeroI16`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `NonZeroI16`, an error is returned. - fn non_zero_i16(&self, key: &str) -> Option>; + fn non_zero_i16(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `NonZeroI32`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `NonZeroI32`, an error is returned. - fn non_zero_i32(&self, key: &str) -> Option>; + fn non_zero_i32(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `NonZeroI64`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `NonZeroI64`, an error is returned. - fn non_zero_i64(&self, key: &str) -> Option>; + fn non_zero_i64(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `NonZeroI128`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `NonZeroI128`, an error is returned. - fn non_zero_i128(&self, key: &str) -> Option>; + fn non_zero_i128(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `NonZeroIsize`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `NonZeroIsize`, an error is returned. - fn non_zero_isize(&self, key: &str) -> Option>; + fn non_zero_isize(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `NonZeroU8`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `NonZeroU8`, an error is returned. - fn non_zero_u8(&self, key: &str) -> Option>; + fn non_zero_u8(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `NonZeroU16`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `NonZeroU16`, an error is returned. - fn non_zero_u16(&self, key: &str) -> Option>; + fn non_zero_u16(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `NonZeroU32`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `NonZeroU32`, an error is returned. - fn non_zero_u32(&self, key: &str) -> Option>; + fn non_zero_u32(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `NonZeroU64`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `NonZeroU64`, an error is returned. - fn non_zero_u64(&self, key: &str) -> Option>; + fn non_zero_u64(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `NonZeroU128`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `NonZeroU128`, an error is returned. - fn non_zero_u128(&self, key: &str) -> Option>; + fn non_zero_u128(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `NonZeroUsize`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `NonZeroUsize`, an error is returned. - fn non_zero_usize(&self, key: &str) -> Option>; + fn non_zero_usize(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `OsString`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `OsString`, an error is returned. - fn os_string(&self, key: &str) -> Option>; + fn os_string(&self, key: &str) -> Option; /// Returns the value of the environment variable `key` as a `PathBuf`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `PathBuf`, an error is returned. - fn path_buf(&self, key: &str) -> Option>; + fn path_buf(&self, key: &str) -> Option; /// Returns the value of the environment variable `key` as a `String`. /// @@ -234,19 +219,19 @@ pub trait Env: Send + Sync { /// /// If the environment variable is not present, `None` is returned. /// If the environment variable is not a valid `SocketAddr`, an error is returned. - fn socket_addr(&self, key: &str) -> Option>; + fn socket_addr(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `SocketAddrV4`. /// /// If the environment variable is not present, `None` is returned. /// If the environment variable is not a valid `SocketAddrV4`, an error is returned. - fn socket_addr_v4(&self, key: &str) -> Option>; + fn socket_addr_v4(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `SocketAddrV6`. /// /// If the environment variable is not present, `None` is returned. /// If the environment variable is not a valid `SocketAddrV6`, an error is returned. - fn socket_addr_v6(&self, key: &str) -> Option>; + fn socket_addr_v6(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `String`. /// @@ -263,37 +248,37 @@ pub trait Env: Send + Sync { /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `u8`, an error is returned. - fn u8(&self, key: &str) -> Option>; + fn u8(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `u16`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `u16`, an error is returned. - fn u16(&self, key: &str) -> Option>; + fn u16(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `u32`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `u32`, an error is returned. - fn u32(&self, key: &str) -> Option>; + fn u32(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `u64`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `u64`, an error is returned. - fn u64(&self, key: &str) -> Option>; + fn u64(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `u128`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is not a valid `u128`, an error is returned. - fn u128(&self, key: &str) -> Option>; + fn u128(&self, key: &str) -> Option>; /// Returns the value of the environment variable `key` as a `usize`. /// /// If the environment variable is not present or it is not a valid unicode, `None` is returned. /// If the environment variable is a valid `usize`, an error is returned. - fn usize(&self, key: &str) -> Option>; + fn usize(&self, key: &str) -> Option>; } // DefaultEnv @@ -305,12 +290,12 @@ pub struct DefaultEnv; impl DefaultEnv { #[inline] - fn var>( + fn parse>( &self, key: &str, - ) -> Option> { + ) -> Option> { match self.raw(key) { - Ok(val) => Some(val.parse::().map_err(|err| EnvParseError(Box::new(err)))), + Ok(val) => Some(val.parse::()), Err(err) => match err { VarError::NotPresent => { trace!(key, "environment variable is not defined"); @@ -323,73 +308,78 @@ impl DefaultEnv { }, } } + + #[inline] + fn var>(&self, key: &str) -> Option { + self.string(key).map(|val| val.into()) + } } impl Env for DefaultEnv { - implementation!(bool); + parse_impl!(bool, ParseBoolError); - implementation!(char); + parse_impl!(char, ParseCharError); - implementation!(f32); + parse_impl!(f32, ParseFloatError); - implementation!(f64); + parse_impl!(f64, ParseFloatError); - implementation!(i8); + parse_impl!(i8, ParseIntError); - implementation!(i16); + parse_impl!(i16, ParseIntError); - implementation!(i32); + parse_impl!(i32, ParseIntError); - implementation!(i64); + parse_impl!(i64, ParseIntError); - implementation!(i128); + parse_impl!(i128, ParseIntError); - implementation!(ip_addr, IpAddr); + parse_impl!(ip_addr, IpAddr, AddrParseError); - implementation!(ipv4_addr, Ipv4Addr); + parse_impl!(ipv4_addr, Ipv4Addr, AddrParseError); - implementation!(ipv6_addr, Ipv6Addr); + parse_impl!(ipv6_addr, Ipv6Addr, AddrParseError); - implementation!(isize); + parse_impl!(isize, ParseIntError); - implementation!(non_zero_i8, NonZeroI8); + parse_impl!(non_zero_i8, NonZeroI8, ParseIntError); - implementation!(non_zero_i16, NonZeroI16); + parse_impl!(non_zero_i16, NonZeroI16, ParseIntError); - implementation!(non_zero_i32, NonZeroI32); + parse_impl!(non_zero_i32, NonZeroI32, ParseIntError); - implementation!(non_zero_i64, NonZeroI64); + parse_impl!(non_zero_i64, NonZeroI64, ParseIntError); - implementation!(non_zero_i128, NonZeroI128); + parse_impl!(non_zero_i128, NonZeroI128, ParseIntError); - implementation!(non_zero_isize, NonZeroIsize); + parse_impl!(non_zero_isize, NonZeroIsize, ParseIntError); - implementation!(non_zero_u8, NonZeroU8); + parse_impl!(non_zero_u8, NonZeroU8, ParseIntError); - implementation!(non_zero_u16, NonZeroU16); + parse_impl!(non_zero_u16, NonZeroU16, ParseIntError); - implementation!(non_zero_u32, NonZeroU32); + parse_impl!(non_zero_u32, NonZeroU32, ParseIntError); - implementation!(non_zero_u64, NonZeroU64); + parse_impl!(non_zero_u64, NonZeroU64, ParseIntError); - implementation!(non_zero_u128, NonZeroU128); + parse_impl!(non_zero_u128, NonZeroU128, ParseIntError); - implementation!(non_zero_usize, NonZeroUsize); + parse_impl!(non_zero_usize, NonZeroUsize, ParseIntError); - implementation!(os_string, OsString); + var_impl!(os_string, OsString); - implementation!(path_buf, PathBuf); + var_impl!(path_buf, PathBuf); fn raw(&self, key: &str) -> Result { trace!(key, "reading environment variable"); std::env::var(key) } - implementation!(socket_addr, SocketAddr); + parse_impl!(socket_addr, SocketAddr, AddrParseError); - implementation!(socket_addr_v4, SocketAddrV4); + parse_impl!(socket_addr_v4, SocketAddrV4, AddrParseError); - implementation!(socket_addr_v6, SocketAddrV6); + parse_impl!(socket_addr_v6, SocketAddrV6, AddrParseError); fn string(&self, key: &str) -> Option { self.raw(key).ok() @@ -406,17 +396,17 @@ impl Env for DefaultEnv { }) } - implementation!(u8); + parse_impl!(u8, ParseIntError); - implementation!(u16); + parse_impl!(u16, ParseIntError); - implementation!(u32); + parse_impl!(u32, ParseIntError); - implementation!(u64); + parse_impl!(u64, ParseIntError); - implementation!(u128); + parse_impl!(u128, ParseIntError); - implementation!(usize); + parse_impl!(usize, ParseIntError); } // MockEnv @@ -431,82 +421,44 @@ mockall::mock! { pub Env {} impl Env for Env { - fn bool(&self, key: &str) -> Option>; - - fn char(&self, key: &str) -> Option>; - - fn f32(&self, key: &str) -> Option>; - - fn f64(&self, key: &str) -> Option>; - - fn i8(&self, key: &str) -> Option>; - - fn i16(&self, key: &str) -> Option>; - - fn i32(&self, key: &str) -> Option>; - - fn i64(&self, key: &str) -> Option>; - - fn i128(&self, key: &str) -> Option>; - - fn ip_addr(&self, key: &str) -> Option>; - - fn ipv4_addr(&self, key: &str) -> Option>; - - fn ipv6_addr(&self, key: &str) -> Option>; - - fn isize(&self, key: &str) -> Option>; - - fn non_zero_i8(&self, key: &str) -> Option>; - - fn non_zero_i16(&self, key: &str) -> Option>; - - fn non_zero_i32(&self, key: &str) -> Option>; - - fn non_zero_i64(&self, key: &str) -> Option>; - - fn non_zero_i128(&self, key: &str) -> Option>; - - fn non_zero_isize(&self, key: &str) -> Option>; - - fn non_zero_u8(&self, key: &str) -> Option>; - - fn non_zero_u16(&self, key: &str) -> Option>; - - fn non_zero_u32(&self, key: &str) -> Option>; - - fn non_zero_u64(&self, key: &str) -> Option>; - - fn non_zero_u128(&self, key: &str) -> Option>; - - fn non_zero_usize(&self, key: &str) -> Option>; - - fn os_string(&self, key: &str) -> Option>; - - fn path_buf(&self, key: &str) -> Option>; - + fn bool(&self, key: &str) -> Option>; + fn char(&self, key: &str) -> Option>; + fn f32(&self, key: &str) -> Option>; + fn f64(&self, key: &str) -> Option>; + fn i8(&self, key: &str) -> Option>; + fn i16(&self, key: &str) -> Option>; + fn i32(&self, key: &str) -> Option>; + fn i64(&self, key: &str) -> Option>; + fn i128(&self, key: &str) -> Option>; + fn ip_addr(&self, key: &str) -> Option>; + fn ipv4_addr(&self, key: &str) -> Option>; + fn ipv6_addr(&self, key: &str) -> Option>; + fn isize(&self, key: &str) -> Option>; + fn non_zero_i8(&self, key: &str) -> Option>; + fn non_zero_i16(&self, key: &str) -> Option>; + fn non_zero_i32(&self, key: &str) -> Option>; + fn non_zero_i64(&self, key: &str) -> Option>; + fn non_zero_i128(&self, key: &str) -> Option>; + fn non_zero_isize(&self, key: &str) -> Option>; + fn non_zero_u8(&self, key: &str) -> Option>; + fn non_zero_u16(&self, key: &str) -> Option>; + fn non_zero_u32(&self, key: &str) -> Option>; + fn non_zero_u64(&self, key: &str) -> Option>; + fn non_zero_u128(&self, key: &str) -> Option>; + fn non_zero_usize(&self, key: &str) -> Option>; + fn os_string(&self, key: &str) -> Option; + fn path_buf(&self, key: &str) -> Option; fn raw(&self, key: &str) -> Result; - - fn socket_addr(&self, key: &str) -> Option>; - - fn socket_addr_v4(&self, key: &str) -> Option>; - - fn socket_addr_v6(&self, key: &str) -> Option>; - + fn socket_addr(&self, key: &str) -> Option>; + fn socket_addr_v4(&self, key: &str) -> Option>; + fn socket_addr_v6(&self, key: &str) -> Option>; fn string(&self, key: &str) -> Option; - fn strings(&self, key: &str, sep: &str) -> Option>; - - fn u8(&self, key: &str) -> Option>; - - fn u16(&self, key: &str) -> Option>; - - fn u32(&self, key: &str) -> Option>; - - fn u64(&self, key: &str) -> Option>; - - fn u128(&self, key: &str) -> Option>; - - fn usize(&self, key: &str) -> Option>; + fn u8(&self, key: &str) -> Option>; + fn u16(&self, key: &str) -> Option>; + fn u32(&self, key: &str) -> Option>; + fn u64(&self, key: &str) -> Option>; + fn u128(&self, key: &str) -> Option>; + fn usize(&self, key: &str) -> Option>; } } diff --git a/src/lib.rs b/src/lib.rs index 1ffd254..35422d7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,7 +17,7 @@ pub use self::uuid::{DefaultUuidGenerator, UuidGenerator}; #[cfg(feature = "mock")] pub use self::{env::MockEnv, sys::MockSystem}; pub use self::{ - env::{DefaultEnv, Env, EnvParseError, EnvParseResult}, + env::{DefaultEnv, Env}, sys::{DefaultSystem, System}, };