standard_lib/fs/path/
dispatch.rs

1use std::str::FromStr;
2
3use crate::fs::error::{EmptyStrError, HomeResolutionError};
4
5use super::{Abs, OwnedPath, Path, PathParseError, Rel};
6
7/// An OwnedPath with a statically dispatched state. TODO
8// TODO: More docs here.
9pub enum DispatchedPath {
10    // No niche optimization for some reason? I thought OsString would have a null niche.
11    Abs(OwnedPath<Abs>),
12    Rel(OwnedPath<Rel>),
13}
14
15impl FromStr for DispatchedPath {
16    // TODO: Is it fair to sanitize in a parse implementation?
17    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            // TODO: Handle '~' more consistently.
27            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            // '.' is caught here, so "./" matches and is then sanitized to a relative "/".
35            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// TODO: Forwarding to generic OwnedPath and Path methods.