Skip to main content

read_url/file/
file_url.rs

1use super::super::{context::*, url::*, util::*};
2
3use std::{fmt, path::*};
4
5//
6// FileUrl
7//
8
9/// A URL for a file or a directory that is locally accessible.
10///
11/// The URL scheme is "file:".
12///
13/// A conforming file URL will have a canonical path (no "." or ".." segments).
14/// If it's a directory then it will end in a path separator.
15///
16/// The path notation depends on the operating system on which this library is
17/// compiled. For example, on Unix-like operating systems the path separator would
18/// be "/" and the root would start with "/",  while on Windows the path separator
19/// would be "\" and the root would start with the drive name and ":\", e.g. "C:\".
20///
21/// However, note that the URL notation is standardized differently. Only "/" is
22/// used as a path separator and for the root. Thus, on Windows "\" becomes a "/".
23/// Preceding the path is "//" plus a host. Because the host is rarely used, file
24/// URLs most often start with "file:///".
25///
26/// For example, on Windows the path "C:\Windows\win.ini" would have the URL
27/// "file:///C:/Windows/win.ini".
28///
29/// This library supports the host for presentation purposes, but it is not
30/// used for [URL::open].
31#[derive(Clone, Debug)]
32pub struct FileUrl {
33    /// The [PathBuf].
34    pub path: PathBuf,
35
36    /// The optional host (for representation purposes only).
37    pub host: Option<String>,
38
39    /// The optional query.
40    pub query: Option<UrlQuery>,
41
42    /// The optional fragment.
43    pub fragment: Option<String>,
44
45    pub(crate) context: UrlContextRef,
46}
47
48impl FileUrl {
49    /// Constructor.
50    pub fn new(
51        context: &UrlContextRef,
52        path: PathBuf,
53        host: Option<String>,
54        query: Option<UrlQuery>,
55        fragment: Option<String>,
56    ) -> Self {
57        Self { host, path, query, fragment, context: context.clone() }
58    }
59
60    /// Constructor.
61    pub fn new_with(&self, path: PathBuf) -> Self {
62        Self::new(&self.context, path, self.host.clone(), self.query.clone(), self.fragment.clone())
63    }
64}
65
66impl fmt::Display for FileUrl {
67    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
68        let host = self.host.as_ref().map_or("", |host| &host);
69        let query = url_query_string(&self.query);
70        let fragment = url_fragment_string(&self.fragment);
71
72        write!(formatter, "file://{}{}{}{}", host, self.path.display(), query, fragment)
73    }
74}
75
76// Conversions
77
78impl Into<UrlRef> for FileUrl {
79    fn into(self) -> UrlRef {
80        Box::new(self)
81    }
82}