read_url/context/
asynchronous.rs1use super::{
2 super::{errors::*, url::*, util::*},
3 context::*,
4};
5
6impl UrlContext {
7 pub async fn url_async(self: &UrlContextRef, url_representation: &str) -> Result<UrlRef, UrlError> {
20 self.url_or_maybe_file_path_async(url_representation, false).await
21 }
22
23 #[cfg(feature = "file")]
40 pub async fn url_or_file_path_async(
41 self: &UrlContextRef,
42 url_or_file_path_representation: &str,
43 ) -> Result<UrlRef, UrlError> {
44 self.url_or_maybe_file_path_async(url_or_file_path_representation, true).await
45 }
46
47 async fn url_or_maybe_file_path_async(
48 self: &UrlContextRef,
49 url_or_file_path_representation: &str,
50 or_file_path: bool,
51 ) -> Result<UrlRef, UrlError> {
52 let url_or_file_path_representation = self.get_url_or_override(url_or_file_path_representation.into())?;
53 match url::Url::parse(&url_or_file_path_representation) {
54 Ok(url) => match url.scheme() {
55 "internal" => {
56 let (query, fragment) = url_query_and_fragment(&url);
57 let url =
58 self.internal_url(url.path().into(), url.host_str().map(|host| host.into()), query, fragment);
59 Ok(url.conform_async()?.await?)
60 }
61
62 #[cfg(feature = "file")]
63 "file" => {
64 let (query, fragment) = url_query_and_fragment(&url);
65 let url = self.file_url(url.path().into(), url.host_str().map(|host| host.into()), query, fragment);
66 Ok(url.conform_async()?.await?)
67 }
68
69 #[cfg(feature = "http")]
70 "http" | "https" => {
71 let url = self.http_url(url);
72 Ok(url.conform_async()?.await?)
73 }
74
75 #[cfg(feature = "tar")]
76 "tar" => {
77 use super::super::tar::*;
78
79 let (archive_url_representation, path) = TarUrl::parse(url.as_str())?;
80
81 let archive_url =
83 Box::pin(self.url_or_maybe_file_path_async(&archive_url_representation, or_file_path)).await?;
84
85 let compression = TarUrl::compression_from(&archive_url)?;
86 let url = self.tar_url(archive_url, path.into(), compression);
87 Ok(url.conform_async()?.await?)
88 }
89
90 #[cfg(feature = "zip")]
91 "zip" => {
92 use super::super::zip::*;
93
94 let (archive_url_representation, path) = ZipUrl::parse(url.as_str())?;
95
96 let archive_url =
98 Box::pin(self.url_or_maybe_file_path_async(&archive_url_representation, or_file_path)).await?;
99
100 let url = self.zip_url(archive_url, path.into());
101 Ok(url.conform_async()?.await?)
102 }
103
104 #[cfg(feature = "git")]
105 "git" => {
106 use super::super::git::*;
107
108 let (repository_url_representation, path) = GitUrl::parse(url.as_str())?;
109 let repository_url = self.absolute_url(&repository_url_representation)?;
110 let url = self.git_url(repository_url, path.into())?;
111 Ok(url.conform_async()?.await?)
112 }
113
114 scheme => Err(UrlError::UnsupportedScheme(scheme.into())),
115 },
116
117 Err(_) => {
119 if or_file_path {
120 #[cfg(feature = "file")]
122 {
123 use std::path::*;
124
125 let path = Path::new(&url_or_file_path_representation);
126 if path.is_absolute() {
127 let url = self.file_url(path.into(), None, None, None);
128 return Ok(url.conform_async()?.await?);
129 }
130 }
131 }
132
133 for base_url in self.base_urls.iter() {
135 let url = base_url.relative(&url_or_file_path_representation);
136 if let Ok(url) = url.conform_async()?.await {
137 return Ok(url);
138 }
139 }
140
141 Err(UrlError::new_io_not_found(url_or_file_path_representation))
142 }
143 }
144 }
145}