pub struct RelativePathBuf { /* private fields */ }
Expand description
A PathBuf
that knows the path of the file it was configured in, if any.
Paths in configuration files are often desired to be relative to the
configuration file itself. For example, a path of a/b.html
configured in a
file /var/config.toml
might be desired to resolve as /var/a/b.html
. This
type makes this possible by simply delcaring the configuration value’s type
as RelativePathBuf
.
§Example
use std::path::Path;
use serde::{Deserialize, Serialize};
use figment::{Figment, value::magic::RelativePathBuf, Jail};
use figment::providers::{Env, Format, Toml, Serialized};
#[derive(Debug, PartialEq, Deserialize, Serialize)]
struct Config {
path: RelativePathBuf,
}
Jail::expect_with(|jail| {
// Note that `jail.directory()` is some non-empty path:
assert_ne!(jail.directory(), Path::new("/"));
// When a path is declared in a file and deserialized as
// `RelativePathBuf`, `relative()` will be relative to the file.
jail.create_file("Config.toml", r#"path = "a/b/c.html""#)?;
let c: Config = Figment::from(Toml::file("Config.toml")).extract()?;
assert_eq!(c.path.original(), Path::new("a/b/c.html"));
assert_eq!(c.path.relative(), jail.directory().join("a/b/c.html"));
assert_ne!(c.path.relative(), Path::new("a/b/c.html"));
// Round-tripping a `RelativePathBuf` preserves path-relativity.
let c: Config = Figment::from(Serialized::defaults(&c)).extract()?;
assert_eq!(c.path.original(), Path::new("a/b/c.html"));
assert_eq!(c.path.relative(), jail.directory().join("a/b/c.html"));
assert_ne!(c.path.relative(), Path::new("a/b/c.html"));
// If a path is declared elsewhere, the "relative" path is the original.
jail.set_env("PATH", "a/b/c.html");
let c: Config = Figment::from(Toml::file("Config.toml"))
.merge(Env::raw().only(&["PATH"]))
.extract()?;
assert_eq!(c.path.original(), Path::new("a/b/c.html"));
assert_eq!(c.path.relative(), Path::new("a/b/c.html"));
// Absolute paths remain unchanged.
jail.create_file("Config.toml", r#"path = "/var/c.html""#);
let c: Config = Figment::from(Toml::file("Config.toml")).extract()?;
assert_eq!(c.path.original(), Path::new("/var/c.html"));
assert_eq!(c.path.relative(), Path::new("/var/c.html"));
// You can use the `From<P: AsRef<Path>>` impl to set defaults:
let figment = Figment::from(Serialized::defaults(Config {
path: "some/default/path".into()
}));
let default: Config = figment.extract()?;
assert_eq!(default.path.original(), Path::new("some/default/path"));
assert_eq!(default.path.relative(), Path::new("some/default/path"));
jail.create_file("Config.toml", r#"path = "an/override""#)?;
let overriden: Config = figment.merge(Toml::file("Config.toml")).extract()?;
assert_eq!(overriden.path.original(), Path::new("an/override"));
assert_eq!(overriden.path.relative(), jail.directory().join("an/override"));
Ok(())
});
§Serialization
By default, a RelativePathBuf
serializes into a structure that can only
deserialize as a RelativePathBuf
. In particular, a RelativePathBuf
does
not serialize into a value compatible with PathBuf
. To serialize into a
Path
, use RelativePathBuf::serialize_original()
or
RelativePathBuf::serialize_relative()
together with serde’s
serialize_with
field attribute:
use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use figment::{Figment, value::magic::RelativePathBuf, Jail};
use figment::providers::{Format, Toml, Serialized};
#[derive(Deserialize, Serialize)]
struct Config {
relative: RelativePathBuf,
#[serde(serialize_with = "RelativePathBuf::serialize_original")]
root: RelativePathBuf,
#[serde(serialize_with = "RelativePathBuf::serialize_relative")]
temp: RelativePathBuf,
}
Jail::expect_with(|jail| {
jail.create_file("Config.toml", r#"
relative = "relative/path"
root = "root/path"
temp = "temp/path"
"#)?;
// Create a figment with a serialize `Config`.
let figment = Figment::from(Toml::file("Config.toml"));
let config = figment.extract::<Config>()?;
let figment = Figment::from(Serialized::defaults(config));
// This fails, as expected.
let relative = figment.extract_inner::<PathBuf>("relative");
assert!(relative.is_err());
// These succeed. This one uses the originally written path.
let root = figment.extract_inner::<PathBuf>("root")?;
assert_eq!(root, PathBuf::from("root/path"));
// This one the magic relative path.
let temp = figment.extract_inner::<PathBuf>("temp")?;
assert_eq!(temp, jail.directory().join("temp/path"));
Ok(())
})
Implementations§
Source§impl RelativePathBuf
impl RelativePathBuf
Sourcepub fn original(&self) -> &Path
pub fn original(&self) -> &Path
Returns the path as it was declared, without modification.
§Example
use std::path::Path;
use figment::{Figment, value::magic::RelativePathBuf, Jail};
use figment::providers::{Format, Toml};
#[derive(Debug, PartialEq, serde::Deserialize)]
struct Config {
path: RelativePathBuf,
}
Jail::expect_with(|jail| {
jail.create_file("Config.toml", r#"path = "hello.html""#)?;
let c: Config = Figment::from(Toml::file("Config.toml")).extract()?;
assert_eq!(c.path.original(), Path::new("hello.html"));
Ok(())
});
Sourcepub fn relative(&self) -> PathBuf
pub fn relative(&self) -> PathBuf
Returns this path resolved relative to the file it was declared in, if any.
If the configured path was relative and it was configured from a file,
this function returns that path prefixed with that file’s parent
directory. Otherwise it returns the original path. Where
config_file_path
is the location of the configuration file, this
corresponds to:
let relative = config_file_path
.parent()
.unwrap()
.join(relative_path_buf.original());
§Example
use std::path::Path;
use figment::{Figment, value::magic::RelativePathBuf, Jail};
use figment::providers::{Env, Format, Toml};
#[derive(Debug, PartialEq, serde::Deserialize)]
struct Config {
path: RelativePathBuf,
}
Jail::expect_with(|jail| {
jail.create_file("Config.toml", r#"path = "hello.html""#)?;
let c: Config = Figment::from(Toml::file("Config.toml")).extract()?;
assert_eq!(c.path.relative(), jail.directory().join("hello.html"));
jail.set_env("PATH", r#"hello.html"#);
let c: Config = Figment::from(Env::raw().only(&["PATH"])).extract()?;
assert_eq!(c.path.relative(), Path::new("hello.html"));
Ok(())
});
Sourcepub fn metadata_path(&self) -> Option<&Path>
pub fn metadata_path(&self) -> Option<&Path>
Returns the path to the file this path was declared in, if any.
§Example
use std::path::Path;
use figment::{Figment, value::magic::RelativePathBuf, Jail};
use figment::providers::{Env, Format, Toml};
#[derive(Debug, PartialEq, serde::Deserialize)]
struct Config {
path: RelativePathBuf,
}
Jail::expect_with(|jail| {
jail.create_file("Config.toml", r#"path = "hello.html""#)?;
let c: Config = Figment::from(Toml::file("Config.toml")).extract()?;
assert_eq!(c.path.metadata_path().unwrap(), jail.directory().join("Config.toml"));
jail.set_env("PATH", r#"hello.html"#);
let c: Config = Figment::from(Env::raw().only(&["PATH"])).extract()?;
assert_eq!(c.path.metadata_path(), None);
Ok(())
});
Sourcepub fn serialize_original<S>(&self, ser: S) -> Result<S::Ok, S::Error>where
S: Serializer,
pub fn serialize_original<S>(&self, ser: S) -> Result<S::Ok, S::Error>where
S: Serializer,
Serialize self
as the original
path.
See serialization for more.
§Example
use std::path::PathBuf;
use figment::value::magic::RelativePathBuf;
use serde::Serialize;
#[derive(Serialize)]
struct Config {
#[serde(serialize_with = "RelativePathBuf::serialize_original")]
path: RelativePathBuf,
}
Sourcepub fn serialize_relative<S>(&self, ser: S) -> Result<S::Ok, S::Error>where
S: Serializer,
pub fn serialize_relative<S>(&self, ser: S) -> Result<S::Ok, S::Error>where
S: Serializer,
Serialize self
as the relative
path.
See serialization for more.
§Example
use std::path::PathBuf;
use figment::value::magic::RelativePathBuf;
use serde::Serialize;
#[derive(Serialize)]
struct Config {
#[serde(serialize_with = "RelativePathBuf::serialize_relative")]
path: RelativePathBuf,
}
Trait Implementations§
Source§impl Clone for RelativePathBuf
impl Clone for RelativePathBuf
Source§fn clone(&self) -> RelativePathBuf
fn clone(&self) -> RelativePathBuf
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl Debug for RelativePathBuf
impl Debug for RelativePathBuf
Source§impl<'de> Deserialize<'de> for RelativePathBuf
impl<'de> Deserialize<'de> for RelativePathBuf
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl<P: AsRef<Path>> From<P> for RelativePathBuf
impl<P: AsRef<Path>> From<P> for RelativePathBuf
Source§fn from(path: P) -> RelativePathBuf
fn from(path: P) -> RelativePathBuf
Source§impl PartialEq for RelativePathBuf
impl PartialEq for RelativePathBuf
Source§impl Serialize for RelativePathBuf
impl Serialize for RelativePathBuf
impl Magic for RelativePathBuf
Auto Trait Implementations§
impl Freeze for RelativePathBuf
impl RefUnwindSafe for RelativePathBuf
impl Send for RelativePathBuf
impl Sync for RelativePathBuf
impl Unpin for RelativePathBuf
impl UnwindSafe for RelativePathBuf
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Layout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...)
attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 48 bytes