1#![doc(html_logo_url = "https: //raw.githubusercontent.com/Wandalen/wTools/master/asset/img/logo_v3_trans_square.png")]
2#![doc(
3 html_favicon_url = "https: //raw.githubusercontent.com/Wandalen/wTools/alpha/asset/img/logo_v3_trans_square_icon_small_v2.ico"
4)]
5#![doc(html_root_url = "https: //docs.rs/crates_tools/latest/crates_tools/")]
6#![ cfg_attr( doc, doc = include_str!( concat!( env!( "CARGO_MANIFEST_DIR" ), "/", "readme.md" ) ) ) ]
7#![ cfg_attr( not( doc ), doc = "Crate management utilities" ) ]
8
9#[ cfg(feature = "enabled") ]
11mod private
12{
13 use std ::collections ::HashMap;
14 use core ::fmt ::Formatter;
15 use std ::io ::Read;
16 use std ::path :: { Path, PathBuf };
17 use core ::time ::Duration;
18 use ureq ::AgentBuilder;
19
20 #[ derive(Default, Clone, PartialEq) ]
22 pub struct CrateArchive(HashMap< PathBuf, Vec<u8 >>);
23
24 impl core ::fmt ::Debug for CrateArchive
25 {
26 #[ allow(clippy ::implicit_return, clippy ::min_ident_chars) ]
27 #[ inline ]
28 fn fmt(&self, f: &mut Formatter< '_ >) -> core ::fmt ::Result
29 {
30 f.debug_struct("CrateArchive").field("files", &self.0.keys()).finish()
31 }
32 }
33
34 impl CrateArchive
35 {
36 #[ allow(clippy ::question_mark_used, clippy ::implicit_return) ]
46 #[ inline ]
47 pub fn read< P >(path: P) -> std ::io ::Result< Self >
48 where
49 P: AsRef< Path >,
50 {
51 let mut file = std ::fs ::File ::open(path)?;
52 let mut buf = vec![];
53 #[ allow(clippy ::verbose_file_reads) ]
54 file.read_to_end(&mut buf)?;
55
56 Self ::decode(buf)
57 }
58
59 #[ cfg(feature = "network") ]
60 #[ allow(clippy ::question_mark_used, clippy ::implicit_return, clippy ::result_large_err) ]
61 #[ inline ]
72 pub fn download< Url >(url: Url) -> Result< Self, ureq ::Error >
73 where
74 Url: AsRef< str >,
75 {
76 let agent = AgentBuilder ::new()
77 .timeout_read(Duration ::from_secs(5))
78 .timeout_write(Duration ::from_secs(5))
79 .build();
80
81 let resp = agent.get(url.as_ref()).call()?;
82
83 let mut buf = vec![];
84 resp.into_reader().read_to_end(&mut buf)?;
85
86 Ok(Self ::decode(buf)?)
87 }
88
89 #[ cfg(feature = "network") ]
101 #[ allow(clippy ::implicit_return, clippy ::result_large_err) ]
102 #[ inline ]
103 pub fn download_crates_io< N, V >(name: N, version: V) -> Result< Self, ureq ::Error >
104 where
105 N: core ::fmt ::Display,
106 V: core ::fmt ::Display,
107 {
108 Self ::download(format!("https://static.crates.io/crates/{name}/{name}-{version}.crate"))
109 }
110
111 #[ allow(clippy ::question_mark_used, unknown_lints, clippy ::implicit_return) ]
121 #[ inline ]
122 pub fn decode< B >(bytes: B) -> std ::io ::Result< Self >
123 where
124 B: AsRef< [u8] >,
125 {
126 use std ::io ::prelude :: *;
127 use flate2 ::bufread ::GzDecoder;
128 use tar ::Archive;
129
130 let bytes_slice = bytes.as_ref();
131 if bytes_slice.is_empty()
132 {
133 return Ok(Self ::default());
134 }
135
136 let gz = GzDecoder ::new(bytes_slice);
137 let mut archive = Archive ::new(gz);
138
139 let mut output = HashMap ::new();
140
141 for file in archive.entries()?
142 {
143 let mut archive_file = file?;
144
145 let mut contents = vec![];
146 archive_file.read_to_end(&mut contents)?;
147
148 output.insert(archive_file.path()?.to_path_buf(), contents);
149 }
150
151 Ok(Self(output))
152 }
153
154 #[ allow(clippy ::implicit_return) ]
156 #[ inline ]
157 pub fn list( &self ) -> Vec< &Path >
158 {
159 self.0.keys().map(PathBuf ::as_path).collect()
160 }
161
162 #[ allow(clippy ::implicit_return) ]
164 #[ inline ]
165 pub fn content_bytes< P >(&self, path: P) -> Option< &[u8] >
166 where
167 P: AsRef< Path >,
168 {
169 self.0.get(path.as_ref()).map(Vec ::as_ref)
170 }
171 }
172}
173
174#[ cfg(feature = "enabled") ]
175#[ doc(inline) ]
176#[ allow(unused_imports, clippy ::pub_use) ]
177pub use own :: *;
178
179#[ cfg(feature = "enabled") ]
181#[ allow(unused_imports) ]
182pub mod own
183{
184 use super ::orphan;
185 #[ doc(inline) ]
186 #[ allow(unused_imports, clippy ::pub_use) ]
187 pub use orphan :: *;
188}
189
190#[ cfg(feature = "enabled") ]
192#[ allow(unused_imports) ]
193pub mod orphan
194{
195 use super ::exposed;
196 #[ doc(inline) ]
197 #[ allow(unused_imports, clippy ::pub_use) ]
198 pub use exposed :: *;
199}
200
201#[ cfg(feature = "enabled") ]
203#[ allow(unused_imports) ]
204pub mod exposed
205{
206 use super ::prelude;
207 #[ doc(inline) ]
208 #[ allow(unused_imports, clippy ::pub_use) ]
209 pub use prelude :: *;
210}
211
212#[ cfg(feature = "enabled") ]
214#[ allow(unused_imports) ]
215pub mod prelude
216{
217 use super ::private;
218 #[ doc(inline) ]
219 #[ allow(unused_imports, clippy ::pub_use) ]
220 pub use private ::CrateArchive;
221}