Skip to content

API Design #12

@Freyskeyd

Description

@Freyskeyd

Hello,

This issue will be the place to discuss about API Design.

The goal of Environment

Environment is a crate to help users on creating/overriding/remove environments variables.

It doesn't directly alter the current thread environment but offer a way to generate a representation of a potential environments.

Features

The user must be able to:

  • Create an empty environment object
  • Create an inherited environment object
  • Update the value of a variable
  • Clear the value of a variable
  • Remove a variable
  • Conditionally apply any of the previously defined actions
  • Convert the environment object as an iterator
  • Create an environment from an Iterator
  • Compare an Environment with another Environment object
  • Compare an Environment with an Iterator
  • Compare a variable's value to a str/string/OsString

Feel free to add more feature here in comments

API Design

Instantiate Objects

You can instantiate an Environment different ways:

// Don't inherit from current thread env
Environment::empty();

// Inherit from current thread env
Environment::inherit();

// Why any type of iterator
Environment::from_iter((0..5).into_iter()
    .map(|x| (format!("KEY_{}", x), x)
);

// With predefined environment variable
Environment::with_var(("foo", "bar"));

// With predefined environment variable
Environment::with_vars(&[("foo", "bar")]);

// Empty environment (macro style)
empty_env!{};

// Inherited environment (macro style)
inherit_env!{};

// Empty environment with_env(macro style)
empty_env!{
     "foo" => "bar"
     "debug" = "true"
};

let env: Environment = vec![("foo", "bar"), ("debug", "true")].into();

To instantiate a variable:

// Created from a tuple
let var: Var = ("foo", "bar").into();

// Created from a slice
let var: Var = &["foo", "bar"].into();

// Created with a key name (Question: must inherit or not?)
Var::new("foo");

// Created from a tuple
Var::from(("foo", "bar"));

// Created from a slice
Var::from(&["foo", "bar"]);

// Created with a key name and inherit
Var::inherit("foo");

Variable manipulations

Here's some variable manipulations:

// Let's assume that `v` is a `Var` instantiate that way `("foo", "bar").into()`
// the `key` is `foo` and the `value` is `bar`.

// Inherit the value from the current thread
v.inherit();

// Override the current value
v.assign("baz");

// Set the current value to an empty string
v.clear();

// Remove the variable from the underlying environment (weird when dealing with only one variable)
v.remove();

// Append a value to the existing one
v.append(";path");

// Condition applied to the next assign
// If the `is` is true, the action is proceed
// If the `isnt` is true, the action is proceed
v.is("bar").assign("baz");
v.isnt("bar").remove();

// `get` return a `to_string_lossy` of the value
assert!(v.get(), "bar");

Integration with Environment object:

To make a fluent API, the Environment object is passed to the Var object

let env = Environment::empty();

// Use the environment object to define two variables (foo and log_level) without condition.
env
    .var("foo").assign("bar")
    .var("log_level").assign("info"); // Environment: [(foo, bar), (log_level, info)]

let env = Environment::with_var(("foo", "bar"));

// The environment stay the same if the condition is not valid
env.var("foo").isnt("bar").assign("baz"); // Environment: [(foo, bar)]

env                  // Environment Object
    .var("foo")      // Var Object
    .assign("bar");  // Environment Object

Contribute

You can contribue to this PR just by commenting it.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions