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}