standard_lib/fs/path/
dispatch.rs1use std::str::FromStr;
2
3use crate::fs::error::{EmptyStrError, HomeResolutionError};
4
5use super::{Abs, OwnedPath, Path, PathParseError, Rel};
6
7pub enum DispatchedPath {
10 Abs(OwnedPath<Abs>),
12 Rel(OwnedPath<Rel>),
13}
14
15impl FromStr for DispatchedPath {
16 type Err = PathParseError;
18
19 fn from_str(s: &str) -> Result<Self, Self::Err> {
20 match s.chars().next() {
21 Some('/') => {
22 Ok(DispatchedPath::Abs(
23 OwnedPath::from_os_str_sanitized(s.as_ref())
24 ))
25 },
26 Some('~') => {
28 Ok(DispatchedPath::Abs(
29 OwnedPath::from_os_str_sanitized(s[1..].as_ref())
30 .resolve_home()
31 .ok_or(HomeResolutionError)?
32 ))
33 },
34 Some(_) => {
36 Ok(DispatchedPath::Rel(
37 OwnedPath::from_os_str_sanitized(s.as_ref())
38 ))
39 },
40 None => Err(EmptyStrError)?,
41 }
42 }
43}
44
45impl DispatchedPath {
46 pub fn abs_or_resolve(self, target: OwnedPath<Abs>) -> OwnedPath<Abs> {
47 match self {
48 DispatchedPath::Abs(abs) => abs,
49 DispatchedPath::Rel(rel) => rel.resolve(target),
50 }
51 }
52
53 pub fn rel_or_make_relative<P: AsRef<Path<Abs>>>(self, target: P) -> OwnedPath<Rel> {
54 match self {
55 DispatchedPath::Abs(abs) => abs.make_relative(target),
56 DispatchedPath::Rel(rel) => rel,
57 }
58 }
59}
60
61