You've already forked uutils.github.io
mirror of
https://github.com/uutils/uutils.github.io.git
synced 2026-06-10 16:12:28 -07:00
deploy: f0e8d44e6e
This commit is contained in:
+106
-36
@@ -357,6 +357,41 @@
|
||||
<a href="#357" id="357">357</a>
|
||||
<a href="#358" id="358">358</a>
|
||||
<a href="#359" id="359">359</a>
|
||||
<a href="#360" id="360">360</a>
|
||||
<a href="#361" id="361">361</a>
|
||||
<a href="#362" id="362">362</a>
|
||||
<a href="#363" id="363">363</a>
|
||||
<a href="#364" id="364">364</a>
|
||||
<a href="#365" id="365">365</a>
|
||||
<a href="#366" id="366">366</a>
|
||||
<a href="#367" id="367">367</a>
|
||||
<a href="#368" id="368">368</a>
|
||||
<a href="#369" id="369">369</a>
|
||||
<a href="#370" id="370">370</a>
|
||||
<a href="#371" id="371">371</a>
|
||||
<a href="#372" id="372">372</a>
|
||||
<a href="#373" id="373">373</a>
|
||||
<a href="#374" id="374">374</a>
|
||||
<a href="#375" id="375">375</a>
|
||||
<a href="#376" id="376">376</a>
|
||||
<a href="#377" id="377">377</a>
|
||||
<a href="#378" id="378">378</a>
|
||||
<a href="#379" id="379">379</a>
|
||||
<a href="#380" id="380">380</a>
|
||||
<a href="#381" id="381">381</a>
|
||||
<a href="#382" id="382">382</a>
|
||||
<a href="#383" id="383">383</a>
|
||||
<a href="#384" id="384">384</a>
|
||||
<a href="#385" id="385">385</a>
|
||||
<a href="#386" id="386">386</a>
|
||||
<a href="#387" id="387">387</a>
|
||||
<a href="#388" id="388">388</a>
|
||||
<a href="#389" id="389">389</a>
|
||||
<a href="#390" id="390">390</a>
|
||||
<a href="#391" id="391">391</a>
|
||||
<a href="#392" id="392">392</a>
|
||||
<a href="#393" id="393">393</a>
|
||||
<a href="#394" id="394">394</a>
|
||||
</pre><pre class="rust"><code><span class="comment">// * This file is part of `fmt` from the uutils coreutils package.
|
||||
// *
|
||||
// * (c) kwantam <kwantam@gmail.com>
|
||||
@@ -370,7 +405,7 @@
|
||||
<span class="kw">use </span>std::cmp;
|
||||
<span class="kw">use </span>std::fs::File;
|
||||
<span class="kw">use </span>std::io::{stdin, stdout, Write};
|
||||
<span class="kw">use </span>std::io::{BufReader, BufWriter, Read};
|
||||
<span class="kw">use </span>std::io::{BufReader, BufWriter, Read, Stdout};
|
||||
<span class="kw">use </span>uucore::display::Quotable;
|
||||
<span class="kw">use </span>uucore::error::{FromIo, UResult, USimpleError};
|
||||
<span class="kw">use </span>uucore::{format_usage, help_about, help_usage, show_warning};
|
||||
@@ -419,10 +454,16 @@
|
||||
goal: usize,
|
||||
tabwidth: usize,
|
||||
}
|
||||
|
||||
<span class="attr">#[uucore::main]
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
</span><span class="kw">pub fn </span>uumain(args: <span class="kw">impl </span>uucore::Args) -> UResult<()> {
|
||||
<span class="doccomment">/// Parse the command line arguments and return the list of files and formatting options.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `args` - Command line arguments.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A tuple containing a vector of file names and a `FmtOptions` struct.
|
||||
</span><span class="kw">fn </span>parse_arguments(args: <span class="kw">impl </span>uucore::Args) -> UResult<(Vec<String>, FmtOptions)> {
|
||||
<span class="kw">let </span>matches = uu_app().try_get_matches_from(args)<span class="question-mark">?</span>;
|
||||
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>files: Vec<String> = matches
|
||||
@@ -536,39 +577,68 @@
|
||||
files.push(<span class="string">"-"</span>.to_owned());
|
||||
}
|
||||
|
||||
<span class="prelude-val">Ok</span>((files, fmt_opts))
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Process the content of a file and format it according to the provided options.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `file_name` - The name of the file to process. A value of "-" represents the standard input.
|
||||
/// * `fmt_opts` - A reference to a `FmtOptions` struct containing the formatting options.
|
||||
/// * `ostream` - A mutable reference to a `BufWriter` wrapping the standard output.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// A `UResult<()>` indicating success or failure.
|
||||
</span><span class="kw">fn </span>process_file(
|
||||
file_name: <span class="kw-2">&</span>str,
|
||||
fmt_opts: <span class="kw-2">&</span>FmtOptions,
|
||||
ostream: <span class="kw-2">&mut </span>BufWriter<Stdout>,
|
||||
) -> UResult<()> {
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>fp = <span class="kw">match </span>file_name {
|
||||
<span class="string">"-" </span>=> BufReader::new(Box::new(stdin()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Read + <span class="lifetime">'static</span>>),
|
||||
<span class="kw">_ </span>=> <span class="kw">match </span>File::open(file_name) {
|
||||
<span class="prelude-val">Ok</span>(f) => BufReader::new(Box::new(f) <span class="kw">as </span>Box<<span class="kw">dyn </span>Read + <span class="lifetime">'static</span>>),
|
||||
<span class="prelude-val">Err</span>(e) => {
|
||||
<span class="macro">show_warning!</span>(<span class="string">"{}: {}"</span>, file_name.maybe_quote(), e);
|
||||
<span class="kw">return </span><span class="prelude-val">Ok</span>(());
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
<span class="kw">let </span>p_stream = ParagraphStream::new(fmt_opts, <span class="kw-2">&mut </span>fp);
|
||||
<span class="kw">for </span>para_result <span class="kw">in </span>p_stream {
|
||||
<span class="kw">match </span>para_result {
|
||||
<span class="prelude-val">Err</span>(s) => {
|
||||
ostream
|
||||
.write_all(s.as_bytes())
|
||||
.map_err_context(|| <span class="string">"failed to write output"</span>.to_string())<span class="question-mark">?</span>;
|
||||
ostream
|
||||
.write_all(<span class="string">b"\n"</span>)
|
||||
.map_err_context(|| <span class="string">"failed to write output"</span>.to_string())<span class="question-mark">?</span>;
|
||||
}
|
||||
<span class="prelude-val">Ok</span>(para) => break_lines(<span class="kw-2">&</span>para, fmt_opts, ostream)
|
||||
.map_err_context(|| <span class="string">"failed to write output"</span>.to_string())<span class="question-mark">?</span>,
|
||||
}
|
||||
}
|
||||
|
||||
<span class="comment">// flush the output after each file
|
||||
</span>ostream
|
||||
.flush()
|
||||
.map_err_context(|| <span class="string">"failed to write output"</span>.to_string())<span class="question-mark">?</span>;
|
||||
|
||||
<span class="prelude-val">Ok</span>(())
|
||||
}
|
||||
|
||||
<span class="attr">#[uucore::main]
|
||||
</span><span class="kw">pub fn </span>uumain(args: <span class="kw">impl </span>uucore::Args) -> UResult<()> {
|
||||
<span class="kw">let </span>(files, fmt_opts) = parse_arguments(args)<span class="question-mark">?</span>;
|
||||
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>ostream = BufWriter::new(stdout());
|
||||
|
||||
<span class="kw">for </span>i <span class="kw">in </span>files.iter().map(|x| <span class="kw-2">&</span>x[..]) {
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>fp = <span class="kw">match </span>i {
|
||||
<span class="string">"-" </span>=> BufReader::new(Box::new(stdin()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Read + <span class="lifetime">'static</span>>),
|
||||
<span class="kw">_ </span>=> <span class="kw">match </span>File::open(i) {
|
||||
<span class="prelude-val">Ok</span>(f) => BufReader::new(Box::new(f) <span class="kw">as </span>Box<<span class="kw">dyn </span>Read + <span class="lifetime">'static</span>>),
|
||||
<span class="prelude-val">Err</span>(e) => {
|
||||
<span class="macro">show_warning!</span>(<span class="string">"{}: {}"</span>, i.maybe_quote(), e);
|
||||
<span class="kw">continue</span>;
|
||||
}
|
||||
},
|
||||
};
|
||||
<span class="kw">let </span>p_stream = ParagraphStream::new(<span class="kw-2">&</span>fmt_opts, <span class="kw-2">&mut </span>fp);
|
||||
<span class="kw">for </span>para_result <span class="kw">in </span>p_stream {
|
||||
<span class="kw">match </span>para_result {
|
||||
<span class="prelude-val">Err</span>(s) => {
|
||||
ostream
|
||||
.write_all(s.as_bytes())
|
||||
.map_err_context(|| <span class="string">"failed to write output"</span>.to_string())<span class="question-mark">?</span>;
|
||||
ostream
|
||||
.write_all(<span class="string">b"\n"</span>)
|
||||
.map_err_context(|| <span class="string">"failed to write output"</span>.to_string())<span class="question-mark">?</span>;
|
||||
}
|
||||
<span class="prelude-val">Ok</span>(para) => break_lines(<span class="kw-2">&</span>para, <span class="kw-2">&</span>fmt_opts, <span class="kw-2">&mut </span>ostream)
|
||||
.map_err_context(|| <span class="string">"failed to write output"</span>.to_string())<span class="question-mark">?</span>,
|
||||
}
|
||||
}
|
||||
|
||||
<span class="comment">// flush the output after each file
|
||||
</span>ostream
|
||||
.flush()
|
||||
.map_err_context(|| <span class="string">"failed to write output"</span>.to_string())<span class="question-mark">?</span>;
|
||||
<span class="kw">for </span>file_name <span class="kw">in </span><span class="kw-2">&</span>files {
|
||||
process_file(file_name, <span class="kw-2">&</span>fmt_opts, <span class="kw-2">&mut </span>ostream)<span class="question-mark">?</span>;
|
||||
}
|
||||
|
||||
<span class="prelude-val">Ok</span>(())
|
||||
|
||||
+257
-159
@@ -721,6 +721,55 @@
|
||||
<a href="#721" id="721">721</a>
|
||||
<a href="#722" id="722">722</a>
|
||||
<a href="#723" id="723">723</a>
|
||||
<a href="#724" id="724">724</a>
|
||||
<a href="#725" id="725">725</a>
|
||||
<a href="#726" id="726">726</a>
|
||||
<a href="#727" id="727">727</a>
|
||||
<a href="#728" id="728">728</a>
|
||||
<a href="#729" id="729">729</a>
|
||||
<a href="#730" id="730">730</a>
|
||||
<a href="#731" id="731">731</a>
|
||||
<a href="#732" id="732">732</a>
|
||||
<a href="#733" id="733">733</a>
|
||||
<a href="#734" id="734">734</a>
|
||||
<a href="#735" id="735">735</a>
|
||||
<a href="#736" id="736">736</a>
|
||||
<a href="#737" id="737">737</a>
|
||||
<a href="#738" id="738">738</a>
|
||||
<a href="#739" id="739">739</a>
|
||||
<a href="#740" id="740">740</a>
|
||||
<a href="#741" id="741">741</a>
|
||||
<a href="#742" id="742">742</a>
|
||||
<a href="#743" id="743">743</a>
|
||||
<a href="#744" id="744">744</a>
|
||||
<a href="#745" id="745">745</a>
|
||||
<a href="#746" id="746">746</a>
|
||||
<a href="#747" id="747">747</a>
|
||||
<a href="#748" id="748">748</a>
|
||||
<a href="#749" id="749">749</a>
|
||||
<a href="#750" id="750">750</a>
|
||||
<a href="#751" id="751">751</a>
|
||||
<a href="#752" id="752">752</a>
|
||||
<a href="#753" id="753">753</a>
|
||||
<a href="#754" id="754">754</a>
|
||||
<a href="#755" id="755">755</a>
|
||||
<a href="#756" id="756">756</a>
|
||||
<a href="#757" id="757">757</a>
|
||||
<a href="#758" id="758">758</a>
|
||||
<a href="#759" id="759">759</a>
|
||||
<a href="#760" id="760">760</a>
|
||||
<a href="#761" id="761">761</a>
|
||||
<a href="#762" id="762">762</a>
|
||||
<a href="#763" id="763">763</a>
|
||||
<a href="#764" id="764">764</a>
|
||||
<a href="#765" id="765">765</a>
|
||||
<a href="#766" id="766">766</a>
|
||||
<a href="#767" id="767">767</a>
|
||||
<a href="#768" id="768">768</a>
|
||||
<a href="#769" id="769">769</a>
|
||||
<a href="#770" id="770">770</a>
|
||||
<a href="#771" id="771">771</a>
|
||||
<a href="#772" id="772">772</a>
|
||||
</pre><pre class="rust"><code><span class="comment">// * This file is part of the uutils coreutils package.
|
||||
// *
|
||||
// * (c) Alex Lyon <arcterus@mail.com>
|
||||
@@ -773,71 +822,140 @@
|
||||
zero: bool,
|
||||
}
|
||||
|
||||
<span class="attr">#[allow(clippy::cognitive_complexity)]
|
||||
<span class="doccomment">/// Creates a Blake2b hasher instance based on the specified length argument.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the length is not a multiple of 8 or if it is greater than 512.
|
||||
</span><span class="kw">fn </span>create_blake2b(matches: <span class="kw-2">&</span>ArgMatches) -> (<span class="kw-2">&</span><span class="lifetime">'static </span>str, Box<<span class="kw">dyn </span>Digest>, usize) {
|
||||
<span class="kw">match </span>matches.get_one::<usize>(<span class="string">"length"</span>) {
|
||||
<span class="prelude-val">Some</span>(<span class="number">0</span>) | <span class="prelude-val">None </span>=> (<span class="string">"BLAKE2"</span>, Box::new(Blake2b::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>, <span class="number">512</span>),
|
||||
<span class="prelude-val">Some</span>(length_in_bits) => {
|
||||
<span class="kw">if </span><span class="kw-2">*</span>length_in_bits > <span class="number">512 </span>{
|
||||
<span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"Invalid length (maximum digest length is 512 bits)"</span>)
|
||||
}
|
||||
|
||||
<span class="kw">if </span>length_in_bits % <span class="number">8 </span>== <span class="number">0 </span>{
|
||||
<span class="kw">let </span>length_in_bytes = length_in_bits / <span class="number">8</span>;
|
||||
(
|
||||
<span class="string">"BLAKE2"</span>,
|
||||
Box::new(Blake2b::with_output_bytes(length_in_bytes)),
|
||||
<span class="kw-2">*</span>length_in_bits,
|
||||
)
|
||||
} <span class="kw">else </span>{
|
||||
<span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"Invalid length (expected a multiple of 8)"</span>)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Creates a SHA3 hasher instance based on the specified bits argument.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if an unsupported output size is provided, or if the `--bits` flag is missing.
|
||||
</span><span class="kw">fn </span>create_sha3(matches: <span class="kw-2">&</span>ArgMatches) -> (<span class="kw-2">&</span><span class="lifetime">'static </span>str, Box<<span class="kw">dyn </span>Digest>, usize) {
|
||||
<span class="kw">match </span>matches.get_one::<usize>(<span class="string">"bits"</span>) {
|
||||
<span class="prelude-val">Some</span>(<span class="number">224</span>) => (
|
||||
<span class="string">"SHA3-224"</span>,
|
||||
Box::new(Sha3_224::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
<span class="number">224</span>,
|
||||
),
|
||||
<span class="prelude-val">Some</span>(<span class="number">256</span>) => (
|
||||
<span class="string">"SHA3-256"</span>,
|
||||
Box::new(Sha3_256::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
<span class="number">256</span>,
|
||||
),
|
||||
<span class="prelude-val">Some</span>(<span class="number">384</span>) => (
|
||||
<span class="string">"SHA3-384"</span>,
|
||||
Box::new(Sha3_384::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
<span class="number">384</span>,
|
||||
),
|
||||
<span class="prelude-val">Some</span>(<span class="number">512</span>) => (
|
||||
<span class="string">"SHA3-512"</span>,
|
||||
Box::new(Sha3_512::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
<span class="number">512</span>,
|
||||
),
|
||||
<span class="prelude-val">Some</span>(<span class="kw">_</span>) => <span class="macro">crash!</span>(
|
||||
<span class="number">1</span>,
|
||||
<span class="string">"Invalid output size for SHA3 (expected 224, 256, 384, or 512)"
|
||||
</span>),
|
||||
<span class="prelude-val">None </span>=> <span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"--bits required for SHA3"</span>),
|
||||
}
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Creates a SHAKE-128 hasher instance based on the specified bits argument.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the `--bits` flag is missing.
|
||||
</span><span class="kw">fn </span>create_shake128(matches: <span class="kw-2">&</span>ArgMatches) -> (<span class="kw-2">&</span><span class="lifetime">'static </span>str, Box<<span class="kw">dyn </span>Digest>, usize) {
|
||||
<span class="kw">match </span>matches.get_one::<usize>(<span class="string">"bits"</span>) {
|
||||
<span class="prelude-val">Some</span>(bits) => (
|
||||
<span class="string">"SHAKE128"</span>,
|
||||
Box::new(Shake128::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
<span class="kw-2">*</span>bits,
|
||||
),
|
||||
<span class="prelude-val">None </span>=> <span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"--bits required for SHAKE-128"</span>),
|
||||
}
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Creates a SHAKE-256 hasher instance based on the specified bits argument.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if the `--bits` flag is missing.
|
||||
</span><span class="kw">fn </span>create_shake256(matches: <span class="kw-2">&</span>ArgMatches) -> (<span class="kw-2">&</span><span class="lifetime">'static </span>str, Box<<span class="kw">dyn </span>Digest>, usize) {
|
||||
<span class="kw">match </span>matches.get_one::<usize>(<span class="string">"bits"</span>) {
|
||||
<span class="prelude-val">Some</span>(bits) => (
|
||||
<span class="string">"SHAKE256"</span>,
|
||||
Box::new(Shake256::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
<span class="kw-2">*</span>bits,
|
||||
),
|
||||
<span class="prelude-val">None </span>=> <span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"--bits required for SHAKE-256"</span>),
|
||||
}
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Detects the hash algorithm from the program name or command-line arguments.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `program` - A string slice containing the program name.
|
||||
/// * `matches` - A reference to the `ArgMatches` object containing the command-line arguments.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
|
||||
</span><span class="kw">fn </span>detect_algo(
|
||||
program: <span class="kw-2">&</span>str,
|
||||
matches: <span class="kw-2">&</span>ArgMatches,
|
||||
) -> (<span class="kw-2">&</span><span class="lifetime">'static </span>str, Box<<span class="kw">dyn </span>Digest + <span class="lifetime">'static</span>>, usize) {
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>alg: <span class="prelude-ty">Option</span><Box<<span class="kw">dyn </span>Digest>> = <span class="prelude-val">None</span>;
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>name: <span class="kw-2">&</span><span class="lifetime">'static </span>str = <span class="string">""</span>;
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>output_bits = <span class="number">0</span>;
|
||||
<span class="kw">match </span>program {
|
||||
<span class="kw">let </span>(name, alg, output_bits) = <span class="kw">match </span>program {
|
||||
<span class="string">"md5sum" </span>=> (<span class="string">"MD5"</span>, Box::new(Md5::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>, <span class="number">128</span>),
|
||||
<span class="string">"sha1sum" </span>=> (<span class="string">"SHA1"</span>, Box::new(Sha1::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>, <span class="number">160</span>),
|
||||
<span class="string">"sha224sum" </span>=> (<span class="string">"SHA224"</span>, Box::new(Sha224::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>, <span class="number">224</span>),
|
||||
<span class="string">"sha256sum" </span>=> (<span class="string">"SHA256"</span>, Box::new(Sha256::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>, <span class="number">256</span>),
|
||||
<span class="string">"sha384sum" </span>=> (<span class="string">"SHA384"</span>, Box::new(Sha384::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>, <span class="number">384</span>),
|
||||
<span class="string">"sha512sum" </span>=> (<span class="string">"SHA512"</span>, Box::new(Sha512::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>, <span class="number">512</span>),
|
||||
<span class="string">"b2sum" </span>=> <span class="kw">match </span>matches.get_one::<usize>(<span class="string">"length"</span>) {
|
||||
<span class="comment">// by default, blake2 uses 64 bytes (512 bits)
|
||||
// --length=0 falls back to default behavior
|
||||
</span><span class="prelude-val">Some</span>(<span class="number">0</span>) | <span class="prelude-val">None </span>=> (<span class="string">"BLAKE2"</span>, Box::new(Blake2b::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>, <span class="number">512</span>),
|
||||
<span class="prelude-val">Some</span>(length_in_bits) => {
|
||||
<span class="kw">if </span><span class="kw-2">*</span>length_in_bits > <span class="number">512 </span>{
|
||||
<span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"Invalid length (maximum digest length is 512 bits)"</span>)
|
||||
}
|
||||
|
||||
<span class="comment">// blake2 output size must be a multiple of 8 bits
|
||||
</span><span class="kw">if </span>length_in_bits % <span class="number">8 </span>== <span class="number">0 </span>{
|
||||
<span class="kw">let </span>length_in_bytes = length_in_bits / <span class="number">8</span>;
|
||||
(
|
||||
<span class="string">"BLAKE2"</span>,
|
||||
Box::new(Blake2b::with_output_bytes(length_in_bytes)),
|
||||
<span class="kw-2">*</span>length_in_bits,
|
||||
)
|
||||
} <span class="kw">else </span>{
|
||||
<span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"Invalid length (expected a multiple of 8)"</span>)
|
||||
}
|
||||
}
|
||||
},
|
||||
<span class="string">"b2sum" </span>=> create_blake2b(matches),
|
||||
<span class="string">"b3sum" </span>=> (<span class="string">"BLAKE3"</span>, Box::new(Blake3::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>, <span class="number">256</span>),
|
||||
<span class="string">"sha3sum" </span>=> <span class="kw">match </span>matches.get_one::<usize>(<span class="string">"bits"</span>) {
|
||||
<span class="prelude-val">Some</span>(<span class="number">224</span>) => (
|
||||
<span class="string">"SHA3-224"</span>,
|
||||
Box::new(Sha3_224::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
<span class="number">224</span>,
|
||||
),
|
||||
<span class="prelude-val">Some</span>(<span class="number">256</span>) => (
|
||||
<span class="string">"SHA3-256"</span>,
|
||||
Box::new(Sha3_256::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
<span class="number">256</span>,
|
||||
),
|
||||
<span class="prelude-val">Some</span>(<span class="number">384</span>) => (
|
||||
<span class="string">"SHA3-384"</span>,
|
||||
Box::new(Sha3_384::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
<span class="number">384</span>,
|
||||
),
|
||||
<span class="prelude-val">Some</span>(<span class="number">512</span>) => (
|
||||
<span class="string">"SHA3-512"</span>,
|
||||
Box::new(Sha3_512::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
<span class="number">512</span>,
|
||||
),
|
||||
<span class="prelude-val">Some</span>(<span class="kw">_</span>) => <span class="macro">crash!</span>(
|
||||
<span class="number">1</span>,
|
||||
<span class="string">"Invalid output size for SHA3 (expected 224, 256, 384, or 512)"
|
||||
</span>),
|
||||
<span class="prelude-val">None </span>=> <span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"--bits required for SHA3"</span>),
|
||||
},
|
||||
<span class="string">"sha3sum" </span>=> create_sha3(matches),
|
||||
<span class="string">"sha3-224sum" </span>=> (
|
||||
<span class="string">"SHA3-224"</span>,
|
||||
Box::new(Sha3_224::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
@@ -858,114 +976,94 @@
|
||||
Box::new(Sha3_512::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
<span class="number">512</span>,
|
||||
),
|
||||
<span class="string">"shake128sum" </span>=> <span class="kw">match </span>matches.get_one::<usize>(<span class="string">"bits"</span>) {
|
||||
<span class="prelude-val">Some</span>(bits) => (
|
||||
<span class="string">"SHAKE128"</span>,
|
||||
Box::new(Shake128::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
<span class="kw-2">*</span>bits,
|
||||
),
|
||||
<span class="string">"shake128sum" </span>=> create_shake128(matches),
|
||||
<span class="string">"shake256sum" </span>=> create_shake256(matches),
|
||||
<span class="kw">_ </span>=> create_algorithm_from_flags(matches),
|
||||
};
|
||||
(name, alg, output_bits)
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Creates a hasher instance based on the command-line flags.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `matches` - A reference to the `ArgMatches` object containing the command-line arguments.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns a tuple containing the algorithm name, the hasher instance, and the output length in bits.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if multiple hash algorithms are specified or if a required flag is missing.
|
||||
</span><span class="kw">fn </span>create_algorithm_from_flags(matches: <span class="kw-2">&</span>ArgMatches) -> (<span class="kw-2">&</span><span class="lifetime">'static </span>str, Box<<span class="kw">dyn </span>Digest>, usize) {
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>alg: <span class="prelude-ty">Option</span><Box<<span class="kw">dyn </span>Digest>> = <span class="prelude-val">None</span>;
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>name: <span class="kw-2">&</span><span class="lifetime">'static </span>str = <span class="string">""</span>;
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>output_bits = <span class="number">0</span>;
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>set_or_crash = |n, val, bits| {
|
||||
<span class="kw">if </span>alg.is_some() {
|
||||
<span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"You cannot combine multiple hash algorithms!"</span>);
|
||||
};
|
||||
name = n;
|
||||
alg = <span class="prelude-val">Some</span>(val);
|
||||
output_bits = bits;
|
||||
};
|
||||
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"md5"</span>) {
|
||||
set_or_crash(<span class="string">"MD5"</span>, Box::new(Md5::new()), <span class="number">128</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha1"</span>) {
|
||||
set_or_crash(<span class="string">"SHA1"</span>, Box::new(Sha1::new()), <span class="number">160</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha224"</span>) {
|
||||
set_or_crash(<span class="string">"SHA224"</span>, Box::new(Sha224::new()), <span class="number">224</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha256"</span>) {
|
||||
set_or_crash(<span class="string">"SHA256"</span>, Box::new(Sha256::new()), <span class="number">256</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha384"</span>) {
|
||||
set_or_crash(<span class="string">"SHA384"</span>, Box::new(Sha384::new()), <span class="number">384</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha512"</span>) {
|
||||
set_or_crash(<span class="string">"SHA512"</span>, Box::new(Sha512::new()), <span class="number">512</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"b2sum"</span>) {
|
||||
set_or_crash(<span class="string">"BLAKE2"</span>, Box::new(Blake2b::new()), <span class="number">512</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"b3sum"</span>) {
|
||||
set_or_crash(<span class="string">"BLAKE3"</span>, Box::new(Blake3::new()), <span class="number">256</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha3"</span>) {
|
||||
<span class="kw">let </span>(n, val, bits) = create_sha3(matches);
|
||||
set_or_crash(n, val, bits);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha3-224"</span>) {
|
||||
set_or_crash(<span class="string">"SHA3-224"</span>, Box::new(Sha3_224::new()), <span class="number">224</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha3-256"</span>) {
|
||||
set_or_crash(<span class="string">"SHA3-256"</span>, Box::new(Sha3_256::new()), <span class="number">256</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha3-384"</span>) {
|
||||
set_or_crash(<span class="string">"SHA3-384"</span>, Box::new(Sha3_384::new()), <span class="number">384</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha3-512"</span>) {
|
||||
set_or_crash(<span class="string">"SHA3-512"</span>, Box::new(Sha3_512::new()), <span class="number">512</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"shake128"</span>) {
|
||||
<span class="kw">match </span>matches.get_one::<usize>(<span class="string">"bits"</span>) {
|
||||
<span class="prelude-val">Some</span>(bits) => set_or_crash(<span class="string">"SHAKE128"</span>, Box::new(Shake128::new()), <span class="kw-2">*</span>bits),
|
||||
<span class="prelude-val">None </span>=> <span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"--bits required for SHAKE-128"</span>),
|
||||
},
|
||||
<span class="string">"shake256sum" </span>=> <span class="kw">match </span>matches.get_one::<usize>(<span class="string">"bits"</span>) {
|
||||
<span class="prelude-val">Some</span>(bits) => (
|
||||
<span class="string">"SHAKE256"</span>,
|
||||
Box::new(Shake256::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
<span class="kw-2">*</span>bits,
|
||||
),
|
||||
<span class="prelude-val">None </span>=> <span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"--bits required for SHAKE-256"</span>),
|
||||
},
|
||||
<span class="kw">_ </span>=> {
|
||||
{
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>set_or_crash = |n, val, bits| {
|
||||
<span class="kw">if </span>alg.is_some() {
|
||||
<span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"You cannot combine multiple hash algorithms!"</span>)
|
||||
};
|
||||
name = n;
|
||||
alg = <span class="prelude-val">Some</span>(val);
|
||||
output_bits = bits;
|
||||
};
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"md5"</span>) {
|
||||
set_or_crash(<span class="string">"MD5"</span>, Box::new(Md5::new()), <span class="number">128</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha1"</span>) {
|
||||
set_or_crash(<span class="string">"SHA1"</span>, Box::new(Sha1::new()), <span class="number">160</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha224"</span>) {
|
||||
set_or_crash(<span class="string">"SHA224"</span>, Box::new(Sha224::new()), <span class="number">224</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha256"</span>) {
|
||||
set_or_crash(<span class="string">"SHA256"</span>, Box::new(Sha256::new()), <span class="number">256</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha384"</span>) {
|
||||
set_or_crash(<span class="string">"SHA384"</span>, Box::new(Sha384::new()), <span class="number">384</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha512"</span>) {
|
||||
set_or_crash(<span class="string">"SHA512"</span>, Box::new(Sha512::new()), <span class="number">512</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"b2sum"</span>) {
|
||||
set_or_crash(<span class="string">"BLAKE2"</span>, Box::new(Blake2b::new()), <span class="number">512</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"b3sum"</span>) {
|
||||
set_or_crash(<span class="string">"BLAKE3"</span>, Box::new(Blake3::new()), <span class="number">256</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha3"</span>) {
|
||||
<span class="kw">match </span>matches.get_one::<usize>(<span class="string">"bits"</span>) {
|
||||
<span class="prelude-val">Some</span>(<span class="number">224</span>) => set_or_crash(
|
||||
<span class="string">"SHA3-224"</span>,
|
||||
Box::new(Sha3_224::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
<span class="number">224</span>,
|
||||
),
|
||||
<span class="prelude-val">Some</span>(<span class="number">256</span>) => set_or_crash(
|
||||
<span class="string">"SHA3-256"</span>,
|
||||
Box::new(Sha3_256::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
<span class="number">256</span>,
|
||||
),
|
||||
<span class="prelude-val">Some</span>(<span class="number">384</span>) => set_or_crash(
|
||||
<span class="string">"SHA3-384"</span>,
|
||||
Box::new(Sha3_384::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
<span class="number">384</span>,
|
||||
),
|
||||
<span class="prelude-val">Some</span>(<span class="number">512</span>) => set_or_crash(
|
||||
<span class="string">"SHA3-512"</span>,
|
||||
Box::new(Sha3_512::new()) <span class="kw">as </span>Box<<span class="kw">dyn </span>Digest>,
|
||||
<span class="number">512</span>,
|
||||
),
|
||||
<span class="prelude-val">Some</span>(<span class="kw">_</span>) => <span class="macro">crash!</span>(
|
||||
<span class="number">1</span>,
|
||||
<span class="string">"Invalid output size for SHA3 (expected 224, 256, 384, or 512)"
|
||||
</span>),
|
||||
<span class="prelude-val">None </span>=> <span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"--bits required for SHA3"</span>),
|
||||
}
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha3-224"</span>) {
|
||||
set_or_crash(<span class="string">"SHA3-224"</span>, Box::new(Sha3_224::new()), <span class="number">224</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha3-256"</span>) {
|
||||
set_or_crash(<span class="string">"SHA3-256"</span>, Box::new(Sha3_256::new()), <span class="number">256</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha3-384"</span>) {
|
||||
set_or_crash(<span class="string">"SHA3-384"</span>, Box::new(Sha3_384::new()), <span class="number">384</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"sha3-512"</span>) {
|
||||
set_or_crash(<span class="string">"SHA3-512"</span>, Box::new(Sha3_512::new()), <span class="number">512</span>);
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"shake128"</span>) {
|
||||
<span class="kw">match </span>matches.get_one::<usize>(<span class="string">"bits"</span>) {
|
||||
<span class="prelude-val">Some</span>(bits) => set_or_crash(<span class="string">"SHAKE128"</span>, Box::new(Shake128::new()), <span class="kw-2">*</span>bits),
|
||||
<span class="prelude-val">None </span>=> <span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"--bits required for SHAKE-128"</span>),
|
||||
}
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"shake256"</span>) {
|
||||
<span class="kw">match </span>matches.get_one::<usize>(<span class="string">"bits"</span>) {
|
||||
<span class="prelude-val">Some</span>(bits) => set_or_crash(<span class="string">"SHAKE256"</span>, Box::new(Shake256::new()), <span class="kw-2">*</span>bits),
|
||||
<span class="prelude-val">None </span>=> <span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"--bits required for SHAKE-256"</span>),
|
||||
}
|
||||
}
|
||||
}
|
||||
<span class="kw">let </span>alg = alg.unwrap_or_else(|| <span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"You must specify hash algorithm!"</span>));
|
||||
(name, alg, output_bits)
|
||||
}
|
||||
}
|
||||
<span class="kw">if </span>matches.get_flag(<span class="string">"shake256"</span>) {
|
||||
<span class="kw">match </span>matches.get_one::<usize>(<span class="string">"bits"</span>) {
|
||||
<span class="prelude-val">Some</span>(bits) => set_or_crash(<span class="string">"SHAKE256"</span>, Box::new(Shake256::new()), <span class="kw-2">*</span>bits),
|
||||
<span class="prelude-val">None </span>=> <span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"--bits required for SHAKE-256"</span>),
|
||||
}
|
||||
}
|
||||
|
||||
<span class="kw">let </span>alg = alg.unwrap_or_else(|| <span class="macro">crash!</span>(<span class="number">1</span>, <span class="string">"You must specify hash algorithm!"</span>));
|
||||
(name, alg, output_bits)
|
||||
}
|
||||
|
||||
<span class="comment">// TODO: return custom error type
|
||||
|
||||
@@ -867,6 +867,85 @@
|
||||
<a href="#867" id="867">867</a>
|
||||
<a href="#868" id="868">868</a>
|
||||
<a href="#869" id="869">869</a>
|
||||
<a href="#870" id="870">870</a>
|
||||
<a href="#871" id="871">871</a>
|
||||
<a href="#872" id="872">872</a>
|
||||
<a href="#873" id="873">873</a>
|
||||
<a href="#874" id="874">874</a>
|
||||
<a href="#875" id="875">875</a>
|
||||
<a href="#876" id="876">876</a>
|
||||
<a href="#877" id="877">877</a>
|
||||
<a href="#878" id="878">878</a>
|
||||
<a href="#879" id="879">879</a>
|
||||
<a href="#880" id="880">880</a>
|
||||
<a href="#881" id="881">881</a>
|
||||
<a href="#882" id="882">882</a>
|
||||
<a href="#883" id="883">883</a>
|
||||
<a href="#884" id="884">884</a>
|
||||
<a href="#885" id="885">885</a>
|
||||
<a href="#886" id="886">886</a>
|
||||
<a href="#887" id="887">887</a>
|
||||
<a href="#888" id="888">888</a>
|
||||
<a href="#889" id="889">889</a>
|
||||
<a href="#890" id="890">890</a>
|
||||
<a href="#891" id="891">891</a>
|
||||
<a href="#892" id="892">892</a>
|
||||
<a href="#893" id="893">893</a>
|
||||
<a href="#894" id="894">894</a>
|
||||
<a href="#895" id="895">895</a>
|
||||
<a href="#896" id="896">896</a>
|
||||
<a href="#897" id="897">897</a>
|
||||
<a href="#898" id="898">898</a>
|
||||
<a href="#899" id="899">899</a>
|
||||
<a href="#900" id="900">900</a>
|
||||
<a href="#901" id="901">901</a>
|
||||
<a href="#902" id="902">902</a>
|
||||
<a href="#903" id="903">903</a>
|
||||
<a href="#904" id="904">904</a>
|
||||
<a href="#905" id="905">905</a>
|
||||
<a href="#906" id="906">906</a>
|
||||
<a href="#907" id="907">907</a>
|
||||
<a href="#908" id="908">908</a>
|
||||
<a href="#909" id="909">909</a>
|
||||
<a href="#910" id="910">910</a>
|
||||
<a href="#911" id="911">911</a>
|
||||
<a href="#912" id="912">912</a>
|
||||
<a href="#913" id="913">913</a>
|
||||
<a href="#914" id="914">914</a>
|
||||
<a href="#915" id="915">915</a>
|
||||
<a href="#916" id="916">916</a>
|
||||
<a href="#917" id="917">917</a>
|
||||
<a href="#918" id="918">918</a>
|
||||
<a href="#919" id="919">919</a>
|
||||
<a href="#920" id="920">920</a>
|
||||
<a href="#921" id="921">921</a>
|
||||
<a href="#922" id="922">922</a>
|
||||
<a href="#923" id="923">923</a>
|
||||
<a href="#924" id="924">924</a>
|
||||
<a href="#925" id="925">925</a>
|
||||
<a href="#926" id="926">926</a>
|
||||
<a href="#927" id="927">927</a>
|
||||
<a href="#928" id="928">928</a>
|
||||
<a href="#929" id="929">929</a>
|
||||
<a href="#930" id="930">930</a>
|
||||
<a href="#931" id="931">931</a>
|
||||
<a href="#932" id="932">932</a>
|
||||
<a href="#933" id="933">933</a>
|
||||
<a href="#934" id="934">934</a>
|
||||
<a href="#935" id="935">935</a>
|
||||
<a href="#936" id="936">936</a>
|
||||
<a href="#937" id="937">937</a>
|
||||
<a href="#938" id="938">938</a>
|
||||
<a href="#939" id="939">939</a>
|
||||
<a href="#940" id="940">940</a>
|
||||
<a href="#941" id="941">941</a>
|
||||
<a href="#942" id="942">942</a>
|
||||
<a href="#943" id="943">943</a>
|
||||
<a href="#944" id="944">944</a>
|
||||
<a href="#945" id="945">945</a>
|
||||
<a href="#946" id="946">946</a>
|
||||
<a href="#947" id="947">947</a>
|
||||
<a href="#948" id="948">948</a>
|
||||
</pre><pre class="rust"><code><span class="comment">// * This file is part of the uutils coreutils package.
|
||||
// *
|
||||
// * (c) Ben Eills <ben@beneills.com>
|
||||
@@ -1551,6 +1630,151 @@
|
||||
<span class="prelude-val">Ok</span>(())
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Perform backup before overwriting.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `to` - The destination file path.
|
||||
/// * `b` - The behavior configuration.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns an Option containing the backup path, or None if backup is not needed.
|
||||
///
|
||||
</span><span class="kw">fn </span>perform_backup(to: <span class="kw-2">&</span>Path, b: <span class="kw-2">&</span>Behavior) -> UResult<<span class="prelude-ty">Option</span><PathBuf>> {
|
||||
<span class="kw">if </span>to.exists() {
|
||||
<span class="kw">if </span>b.verbose {
|
||||
<span class="macro">println!</span>(<span class="string">"removed {}"</span>, to.quote());
|
||||
}
|
||||
<span class="kw">let </span>backup_path = backup_control::get_backup_path(b.backup_mode, to, <span class="kw-2">&</span>b.suffix);
|
||||
<span class="kw">if let </span><span class="prelude-val">Some</span>(<span class="kw-2">ref </span>backup_path) = backup_path {
|
||||
<span class="comment">// TODO!!
|
||||
</span><span class="kw">if let </span><span class="prelude-val">Err</span>(err) = fs::rename(to, backup_path) {
|
||||
<span class="kw">return </span><span class="prelude-val">Err</span>(InstallError::BackupFailed(
|
||||
to.to_path_buf(),
|
||||
backup_path.to_path_buf(),
|
||||
err,
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
<span class="prelude-val">Ok</span>(backup_path)
|
||||
} <span class="kw">else </span>{
|
||||
<span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>)
|
||||
}
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Copy a file from one path to another.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `from` - The source file path.
|
||||
/// * `to` - The destination file path.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns an empty Result or an error in case of failure.
|
||||
///
|
||||
</span><span class="kw">fn </span>copy_file(from: <span class="kw-2">&</span>Path, to: <span class="kw-2">&</span>Path) -> UResult<()> {
|
||||
<span class="kw">if </span>from.as_os_str() == <span class="string">"/dev/null" </span>{
|
||||
<span class="comment">/* workaround a limitation of fs::copy
|
||||
* https://github.com/rust-lang/rust/issues/79390
|
||||
*/
|
||||
</span><span class="kw">if let </span><span class="prelude-val">Err</span>(err) = File::create(to) {
|
||||
<span class="kw">return </span><span class="prelude-val">Err</span>(
|
||||
InstallError::InstallFailed(from.to_path_buf(), to.to_path_buf(), err).into(),
|
||||
);
|
||||
}
|
||||
} <span class="kw">else if let </span><span class="prelude-val">Err</span>(err) = fs::copy(from, to) {
|
||||
<span class="kw">return </span><span class="prelude-val">Err</span>(InstallError::InstallFailed(from.to_path_buf(), to.to_path_buf(), err).into());
|
||||
}
|
||||
<span class="prelude-val">Ok</span>(())
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Strip a file using an external program.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `to` - The destination file path.
|
||||
/// * `b` - The behavior configuration.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns an empty Result or an error in case of failure.
|
||||
///
|
||||
</span><span class="kw">fn </span>strip_file(to: <span class="kw-2">&</span>Path, b: <span class="kw-2">&</span>Behavior) -> UResult<()> {
|
||||
<span class="kw">match </span>process::Command::new(<span class="kw-2">&</span>b.strip_program).arg(to).output() {
|
||||
<span class="prelude-val">Ok</span>(o) => {
|
||||
<span class="kw">if </span>!o.status.success() {
|
||||
<span class="comment">// Follow GNU's behavior: if strip fails, removes the target
|
||||
</span><span class="kw">let _ </span>= fs::remove_file(to);
|
||||
<span class="kw">return </span><span class="prelude-val">Err</span>(InstallError::StripProgramFailed(
|
||||
String::from_utf8(o.stderr).unwrap_or_default(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
<span class="prelude-val">Err</span>(e) => {
|
||||
<span class="comment">// Follow GNU's behavior: if strip fails, removes the target
|
||||
</span><span class="kw">let _ </span>= fs::remove_file(to);
|
||||
<span class="kw">return </span><span class="prelude-val">Err</span>(InstallError::StripProgramFailed(e.to_string()).into());
|
||||
}
|
||||
}
|
||||
<span class="prelude-val">Ok</span>(())
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Set ownership and permissions on the destination file.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `to` - The destination file path.
|
||||
/// * `b` - The behavior configuration.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns an empty Result or an error in case of failure.
|
||||
///
|
||||
</span><span class="kw">fn </span>set_ownership_and_permissions(to: <span class="kw-2">&</span>Path, b: <span class="kw-2">&</span>Behavior) -> UResult<()> {
|
||||
<span class="comment">// Silent the warning as we want to the error message
|
||||
</span><span class="attr">#[allow(clippy::question_mark)]
|
||||
</span><span class="kw">if </span>mode::chmod(to, b.mode()).is_err() {
|
||||
<span class="kw">return </span><span class="prelude-val">Err</span>(InstallError::ChmodFailed(to.to_path_buf()).into());
|
||||
}
|
||||
|
||||
chown_optional_user_group(to, b)<span class="question-mark">?</span>;
|
||||
|
||||
<span class="prelude-val">Ok</span>(())
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Preserve timestamps on the destination file.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `from` - The source file path.
|
||||
/// * `to` - The destination file path.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// Returns an empty Result or an error in case of failure.
|
||||
///
|
||||
</span><span class="kw">fn </span>preserve_timestamps(from: <span class="kw-2">&</span>Path, to: <span class="kw-2">&</span>Path) -> UResult<()> {
|
||||
<span class="kw">let </span>meta = <span class="kw">match </span>fs::metadata(from) {
|
||||
<span class="prelude-val">Ok</span>(meta) => meta,
|
||||
<span class="prelude-val">Err</span>(e) => <span class="kw">return </span><span class="prelude-val">Err</span>(InstallError::MetadataFailed(e).into()),
|
||||
};
|
||||
|
||||
<span class="kw">let </span>modified_time = FileTime::from_last_modification_time(<span class="kw-2">&</span>meta);
|
||||
<span class="kw">let </span>accessed_time = FileTime::from_last_access_time(<span class="kw-2">&</span>meta);
|
||||
|
||||
<span class="kw">match </span>set_file_times(to, accessed_time, modified_time) {
|
||||
<span class="prelude-val">Ok</span>(<span class="kw">_</span>) => <span class="prelude-val">Ok</span>(()),
|
||||
<span class="prelude-val">Err</span>(e) => {
|
||||
<span class="macro">show_error!</span>(<span class="string">"{}"</span>, e);
|
||||
<span class="prelude-val">Ok</span>(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Copy one file to a new location, changing metadata.
|
||||
///
|
||||
/// Returns a Result type with the Err variant containing the error message.
|
||||
@@ -1564,90 +1788,24 @@
|
||||
///
|
||||
/// If the copy system call fails, we print a verbose error and return an empty error value.
|
||||
///
|
||||
</span><span class="attr">#[allow(clippy::cognitive_complexity)]
|
||||
</span><span class="kw">fn </span>copy(from: <span class="kw-2">&</span>Path, to: <span class="kw-2">&</span>Path, b: <span class="kw-2">&</span>Behavior) -> UResult<()> {
|
||||
<span class="kw">if </span>b.compare && !need_copy(from, to, b)<span class="question-mark">? </span>{
|
||||
<span class="kw">return </span><span class="prelude-val">Ok</span>(());
|
||||
}
|
||||
<span class="comment">// Declare the path here as we may need it for the verbose output below.
|
||||
</span><span class="kw">let </span><span class="kw-2">mut </span>backup_path = <span class="prelude-val">None</span>;
|
||||
</span><span class="kw">let </span>backup_path = perform_backup(to, b)<span class="question-mark">?</span>;
|
||||
|
||||
<span class="comment">// Perform backup, if any, before overwriting 'to'
|
||||
//
|
||||
// The codes actually making use of the backup process don't seem to agree
|
||||
// on how best to approach the issue. (mv and ln, for example)
|
||||
</span><span class="kw">if </span>to.exists() {
|
||||
<span class="kw">if </span>b.verbose {
|
||||
<span class="macro">println!</span>(<span class="string">"removed {}"</span>, to.quote());
|
||||
}
|
||||
backup_path = backup_control::get_backup_path(b.backup_mode, to, <span class="kw-2">&</span>b.suffix);
|
||||
<span class="kw">if let </span><span class="prelude-val">Some</span>(<span class="kw-2">ref </span>backup_path) = backup_path {
|
||||
<span class="comment">// TODO!!
|
||||
</span><span class="kw">if let </span><span class="prelude-val">Err</span>(err) = fs::rename(to, backup_path) {
|
||||
<span class="kw">return </span><span class="prelude-val">Err</span>(InstallError::BackupFailed(
|
||||
to.to_path_buf(),
|
||||
backup_path.to_path_buf(),
|
||||
err,
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
copy_file(from, to)<span class="question-mark">?</span>;
|
||||
|
||||
<span class="attr">#[cfg(not(windows))]
|
||||
</span><span class="kw">if </span>b.strip {
|
||||
strip_file(to, b)<span class="question-mark">?</span>;
|
||||
}
|
||||
|
||||
<span class="kw">if </span>from.as_os_str() == <span class="string">"/dev/null" </span>{
|
||||
<span class="comment">/* workaround a limitation of fs::copy
|
||||
* https://github.com/rust-lang/rust/issues/79390
|
||||
*/
|
||||
</span><span class="kw">if let </span><span class="prelude-val">Err</span>(err) = File::create(to) {
|
||||
<span class="kw">return </span><span class="prelude-val">Err</span>(
|
||||
InstallError::InstallFailed(from.to_path_buf(), to.to_path_buf(), err).into(),
|
||||
);
|
||||
}
|
||||
} <span class="kw">else if let </span><span class="prelude-val">Err</span>(err) = fs::copy(from, to) {
|
||||
<span class="kw">return </span><span class="prelude-val">Err</span>(InstallError::InstallFailed(from.to_path_buf(), to.to_path_buf(), err).into());
|
||||
}
|
||||
|
||||
<span class="kw">if </span>b.strip && <span class="macro">cfg!</span>(not(windows)) {
|
||||
<span class="kw">match </span>process::Command::new(<span class="kw-2">&</span>b.strip_program).arg(to).output() {
|
||||
<span class="prelude-val">Ok</span>(o) => {
|
||||
<span class="kw">if </span>!o.status.success() {
|
||||
<span class="comment">// Follow GNU's behavior: if strip fails, removes the target
|
||||
</span><span class="kw">let _ </span>= fs::remove_file(to);
|
||||
<span class="kw">return </span><span class="prelude-val">Err</span>(InstallError::StripProgramFailed(
|
||||
String::from_utf8(o.stderr).unwrap_or_default(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
}
|
||||
<span class="prelude-val">Err</span>(e) => {
|
||||
<span class="comment">// Follow GNU's behavior: if strip fails, removes the target
|
||||
</span><span class="kw">let _ </span>= fs::remove_file(to);
|
||||
<span class="kw">return </span><span class="prelude-val">Err</span>(InstallError::StripProgramFailed(e.to_string()).into());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<span class="comment">// Silent the warning as we want to the error message
|
||||
</span><span class="attr">#[allow(clippy::question_mark)]
|
||||
</span><span class="kw">if </span>mode::chmod(to, b.mode()).is_err() {
|
||||
<span class="kw">return </span><span class="prelude-val">Err</span>(InstallError::ChmodFailed(to.to_path_buf()).into());
|
||||
}
|
||||
|
||||
chown_optional_user_group(to, b)<span class="question-mark">?</span>;
|
||||
set_ownership_and_permissions(to, b)<span class="question-mark">?</span>;
|
||||
|
||||
<span class="kw">if </span>b.preserve_timestamps {
|
||||
<span class="kw">let </span>meta = <span class="kw">match </span>fs::metadata(from) {
|
||||
<span class="prelude-val">Ok</span>(meta) => meta,
|
||||
<span class="prelude-val">Err</span>(e) => <span class="kw">return </span><span class="prelude-val">Err</span>(InstallError::MetadataFailed(e).into()),
|
||||
};
|
||||
|
||||
<span class="kw">let </span>modified_time = FileTime::from_last_modification_time(<span class="kw-2">&</span>meta);
|
||||
<span class="kw">let </span>accessed_time = FileTime::from_last_access_time(<span class="kw-2">&</span>meta);
|
||||
|
||||
<span class="kw">match </span>set_file_times(to, accessed_time, modified_time) {
|
||||
<span class="prelude-val">Ok</span>(<span class="kw">_</span>) => {}
|
||||
<span class="prelude-val">Err</span>(e) => <span class="macro">show_error!</span>(<span class="string">"{}"</span>, e),
|
||||
}
|
||||
preserve_timestamps(from, to)<span class="question-mark">?</span>;
|
||||
}
|
||||
|
||||
<span class="kw">if </span>b.verbose {
|
||||
|
||||
+264
-56
@@ -933,6 +933,110 @@
|
||||
<a href="#933" id="933">933</a>
|
||||
<a href="#934" id="934">934</a>
|
||||
<a href="#935" id="935">935</a>
|
||||
<a href="#936" id="936">936</a>
|
||||
<a href="#937" id="937">937</a>
|
||||
<a href="#938" id="938">938</a>
|
||||
<a href="#939" id="939">939</a>
|
||||
<a href="#940" id="940">940</a>
|
||||
<a href="#941" id="941">941</a>
|
||||
<a href="#942" id="942">942</a>
|
||||
<a href="#943" id="943">943</a>
|
||||
<a href="#944" id="944">944</a>
|
||||
<a href="#945" id="945">945</a>
|
||||
<a href="#946" id="946">946</a>
|
||||
<a href="#947" id="947">947</a>
|
||||
<a href="#948" id="948">948</a>
|
||||
<a href="#949" id="949">949</a>
|
||||
<a href="#950" id="950">950</a>
|
||||
<a href="#951" id="951">951</a>
|
||||
<a href="#952" id="952">952</a>
|
||||
<a href="#953" id="953">953</a>
|
||||
<a href="#954" id="954">954</a>
|
||||
<a href="#955" id="955">955</a>
|
||||
<a href="#956" id="956">956</a>
|
||||
<a href="#957" id="957">957</a>
|
||||
<a href="#958" id="958">958</a>
|
||||
<a href="#959" id="959">959</a>
|
||||
<a href="#960" id="960">960</a>
|
||||
<a href="#961" id="961">961</a>
|
||||
<a href="#962" id="962">962</a>
|
||||
<a href="#963" id="963">963</a>
|
||||
<a href="#964" id="964">964</a>
|
||||
<a href="#965" id="965">965</a>
|
||||
<a href="#966" id="966">966</a>
|
||||
<a href="#967" id="967">967</a>
|
||||
<a href="#968" id="968">968</a>
|
||||
<a href="#969" id="969">969</a>
|
||||
<a href="#970" id="970">970</a>
|
||||
<a href="#971" id="971">971</a>
|
||||
<a href="#972" id="972">972</a>
|
||||
<a href="#973" id="973">973</a>
|
||||
<a href="#974" id="974">974</a>
|
||||
<a href="#975" id="975">975</a>
|
||||
<a href="#976" id="976">976</a>
|
||||
<a href="#977" id="977">977</a>
|
||||
<a href="#978" id="978">978</a>
|
||||
<a href="#979" id="979">979</a>
|
||||
<a href="#980" id="980">980</a>
|
||||
<a href="#981" id="981">981</a>
|
||||
<a href="#982" id="982">982</a>
|
||||
<a href="#983" id="983">983</a>
|
||||
<a href="#984" id="984">984</a>
|
||||
<a href="#985" id="985">985</a>
|
||||
<a href="#986" id="986">986</a>
|
||||
<a href="#987" id="987">987</a>
|
||||
<a href="#988" id="988">988</a>
|
||||
<a href="#989" id="989">989</a>
|
||||
<a href="#990" id="990">990</a>
|
||||
<a href="#991" id="991">991</a>
|
||||
<a href="#992" id="992">992</a>
|
||||
<a href="#993" id="993">993</a>
|
||||
<a href="#994" id="994">994</a>
|
||||
<a href="#995" id="995">995</a>
|
||||
<a href="#996" id="996">996</a>
|
||||
<a href="#997" id="997">997</a>
|
||||
<a href="#998" id="998">998</a>
|
||||
<a href="#999" id="999">999</a>
|
||||
<a href="#1000" id="1000">1000</a>
|
||||
<a href="#1001" id="1001">1001</a>
|
||||
<a href="#1002" id="1002">1002</a>
|
||||
<a href="#1003" id="1003">1003</a>
|
||||
<a href="#1004" id="1004">1004</a>
|
||||
<a href="#1005" id="1005">1005</a>
|
||||
<a href="#1006" id="1006">1006</a>
|
||||
<a href="#1007" id="1007">1007</a>
|
||||
<a href="#1008" id="1008">1008</a>
|
||||
<a href="#1009" id="1009">1009</a>
|
||||
<a href="#1010" id="1010">1010</a>
|
||||
<a href="#1011" id="1011">1011</a>
|
||||
<a href="#1012" id="1012">1012</a>
|
||||
<a href="#1013" id="1013">1013</a>
|
||||
<a href="#1014" id="1014">1014</a>
|
||||
<a href="#1015" id="1015">1015</a>
|
||||
<a href="#1016" id="1016">1016</a>
|
||||
<a href="#1017" id="1017">1017</a>
|
||||
<a href="#1018" id="1018">1018</a>
|
||||
<a href="#1019" id="1019">1019</a>
|
||||
<a href="#1020" id="1020">1020</a>
|
||||
<a href="#1021" id="1021">1021</a>
|
||||
<a href="#1022" id="1022">1022</a>
|
||||
<a href="#1023" id="1023">1023</a>
|
||||
<a href="#1024" id="1024">1024</a>
|
||||
<a href="#1025" id="1025">1025</a>
|
||||
<a href="#1026" id="1026">1026</a>
|
||||
<a href="#1027" id="1027">1027</a>
|
||||
<a href="#1028" id="1028">1028</a>
|
||||
<a href="#1029" id="1029">1029</a>
|
||||
<a href="#1030" id="1030">1030</a>
|
||||
<a href="#1031" id="1031">1031</a>
|
||||
<a href="#1032" id="1032">1032</a>
|
||||
<a href="#1033" id="1033">1033</a>
|
||||
<a href="#1034" id="1034">1034</a>
|
||||
<a href="#1035" id="1035">1035</a>
|
||||
<a href="#1036" id="1036">1036</a>
|
||||
<a href="#1037" id="1037">1037</a>
|
||||
<a href="#1038" id="1038">1038</a>
|
||||
<a href="#1039" id="1039">1039</a>
|
||||
</pre><pre class="rust"><code><span class="comment">// This file is part of the uutils coreutils package.
|
||||
//
|
||||
// (c) Jian Zeng <anonymousknight96@gmail.com>
|
||||
@@ -1140,7 +1244,16 @@
|
||||
default_dev_tokens: Vec<Token>,
|
||||
}
|
||||
|
||||
<span class="attr">#[allow(clippy::cognitive_complexity)]
|
||||
<span class="doccomment">/// Prints a formatted output based on the provided output type, flags, width, and precision.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `output` - A reference to the OutputType enum containing the value to be printed.
|
||||
/// * `flags` - A Flags struct containing formatting flags.
|
||||
/// * `width` - The width of the field for the printed output.
|
||||
/// * `precision` - An Option containing the precision value.
|
||||
///
|
||||
/// This function delegates the printing process to more specialized functions depending on the output type.
|
||||
</span><span class="kw">fn </span>print_it(output: <span class="kw-2">&</span>OutputType, flags: Flags, width: usize, precision: <span class="prelude-ty">Option</span><usize>) {
|
||||
<span class="comment">// If the precision is given as just '.', the precision is taken to be zero.
|
||||
// A negative precision is taken as if the precision were omitted.
|
||||
@@ -1171,71 +1284,166 @@
|
||||
// A sign (+ or -) should always be placed before a number produced by a signed conversion.
|
||||
// By default, a sign is used only for negative numbers.
|
||||
// A + overrides a space if both are used.
|
||||
|
||||
</span><span class="kw">let </span>padding_char = <span class="kw">if </span>flags.zero && !flags.left && precision.is_none() {
|
||||
Padding::Zero
|
||||
} <span class="kw">else </span>{
|
||||
Padding::Space
|
||||
};
|
||||
</span><span class="kw">let </span>padding_char = determine_padding_char(<span class="kw-2">&</span>flags, <span class="kw-2">&</span>precision);
|
||||
|
||||
<span class="kw">match </span>output {
|
||||
OutputType::Str(s) => {
|
||||
<span class="kw">let </span>s = <span class="kw">match </span>precision {
|
||||
<span class="prelude-val">Some</span>(p) <span class="kw">if </span>p < s.len() => <span class="kw-2">&</span>s[..p],
|
||||
<span class="kw">_ </span>=> s,
|
||||
};
|
||||
pad_and_print(s, flags.left, width, Padding::Space);
|
||||
}
|
||||
OutputType::Integer(num) => {
|
||||
<span class="kw">let </span>num = num.to_string();
|
||||
<span class="kw">let </span>arg = <span class="kw">if </span>flags.group {
|
||||
group_num(<span class="kw-2">&</span>num)
|
||||
} <span class="kw">else </span>{
|
||||
Cow::Borrowed(num.as_str())
|
||||
};
|
||||
<span class="kw">let </span>prefix = <span class="kw">if </span>flags.sign {
|
||||
<span class="string">"+"
|
||||
</span>} <span class="kw">else if </span>flags.space {
|
||||
<span class="string">" "
|
||||
</span>} <span class="kw">else </span>{
|
||||
<span class="string">""
|
||||
</span>};
|
||||
<span class="kw">let </span>extended = <span class="macro">format!</span>(
|
||||
<span class="string">"{prefix}{arg:0>precision$}"</span>,
|
||||
precision = precision.unwrap_or(<span class="number">0</span>)
|
||||
);
|
||||
pad_and_print(<span class="kw-2">&</span>extended, flags.left, width, padding_char);
|
||||
}
|
||||
OutputType::Unsigned(num) => {
|
||||
<span class="kw">let </span>num = num.to_string();
|
||||
<span class="kw">let </span>s = <span class="kw">if </span>flags.group {
|
||||
group_num(<span class="kw-2">&</span>num)
|
||||
} <span class="kw">else </span>{
|
||||
Cow::Borrowed(num.as_str())
|
||||
};
|
||||
<span class="kw">let </span>s = <span class="macro">format!</span>(<span class="string">"{s:0>precision$}"</span>, precision = precision.unwrap_or(<span class="number">0</span>));
|
||||
pad_and_print(<span class="kw-2">&</span>s, flags.left, width, padding_char);
|
||||
}
|
||||
OutputType::Str(s) => print_str(s, <span class="kw-2">&</span>flags, width, precision),
|
||||
OutputType::Integer(num) => print_integer(<span class="kw-2">*</span>num, <span class="kw-2">&</span>flags, width, precision, padding_char),
|
||||
OutputType::Unsigned(num) => print_unsigned(<span class="kw-2">*</span>num, <span class="kw-2">&</span>flags, width, precision, padding_char),
|
||||
OutputType::UnsignedOct(num) => {
|
||||
<span class="kw">let </span>prefix = <span class="kw">if </span>flags.alter { <span class="string">"0" </span>} <span class="kw">else </span>{ <span class="string">"" </span>};
|
||||
<span class="kw">let </span>s = <span class="macro">format!</span>(
|
||||
<span class="string">"{prefix}{num:0>precision$o}"</span>,
|
||||
precision = precision.unwrap_or(<span class="number">0</span>)
|
||||
);
|
||||
pad_and_print(<span class="kw-2">&</span>s, flags.left, width, padding_char);
|
||||
print_unsigned_oct(<span class="kw-2">*</span>num, <span class="kw-2">&</span>flags, width, precision, padding_char);
|
||||
}
|
||||
OutputType::UnsignedHex(num) => {
|
||||
<span class="kw">let </span>prefix = <span class="kw">if </span>flags.alter { <span class="string">"0x" </span>} <span class="kw">else </span>{ <span class="string">"" </span>};
|
||||
<span class="kw">let </span>s = <span class="macro">format!</span>(
|
||||
<span class="string">"{prefix}{num:0>precision$x}"</span>,
|
||||
precision = precision.unwrap_or(<span class="number">0</span>)
|
||||
);
|
||||
pad_and_print(<span class="kw-2">&</span>s, flags.left, width, padding_char);
|
||||
print_unsigned_hex(<span class="kw-2">*</span>num, <span class="kw-2">&</span>flags, width, precision, padding_char);
|
||||
}
|
||||
OutputType::Unknown => <span class="macro">print!</span>(<span class="string">"?"</span>),
|
||||
}
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Determines the padding character based on the provided flags and precision.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `flags` - A reference to the Flags struct containing formatting flags.
|
||||
/// * `precision` - An Option containing the precision value.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// * Padding - An instance of the Padding enum representing the padding character.
|
||||
</span><span class="kw">fn </span>determine_padding_char(flags: <span class="kw-2">&</span>Flags, precision: <span class="kw-2">&</span><span class="prelude-ty">Option</span><usize>) -> Padding {
|
||||
<span class="kw">if </span>flags.zero && !flags.left && precision.is_none() {
|
||||
Padding::Zero
|
||||
} <span class="kw">else </span>{
|
||||
Padding::Space
|
||||
}
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Prints a string value based on the provided flags, width, and precision.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `s` - The string to be printed.
|
||||
/// * `flags` - A reference to the Flags struct containing formatting flags.
|
||||
/// * `width` - The width of the field for the printed string.
|
||||
/// * `precision` - An Option containing the precision value.
|
||||
</span><span class="kw">fn </span>print_str(s: <span class="kw-2">&</span>str, flags: <span class="kw-2">&</span>Flags, width: usize, precision: <span class="prelude-ty">Option</span><usize>) {
|
||||
<span class="kw">let </span>s = <span class="kw">match </span>precision {
|
||||
<span class="prelude-val">Some</span>(p) <span class="kw">if </span>p < s.len() => <span class="kw-2">&</span>s[..p],
|
||||
<span class="kw">_ </span>=> s,
|
||||
};
|
||||
pad_and_print(s, flags.left, width, Padding::Space);
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Prints an integer value based on the provided flags, width, and precision.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `num` - The integer value to be printed.
|
||||
/// * `flags` - A reference to the Flags struct containing formatting flags.
|
||||
/// * `width` - The width of the field for the printed integer.
|
||||
/// * `precision` - An Option containing the precision value.
|
||||
/// * `padding_char` - The padding character as determined by `determine_padding_char`.
|
||||
</span><span class="kw">fn </span>print_integer(
|
||||
num: i64,
|
||||
flags: <span class="kw-2">&</span>Flags,
|
||||
width: usize,
|
||||
precision: <span class="prelude-ty">Option</span><usize>,
|
||||
padding_char: Padding,
|
||||
) {
|
||||
<span class="kw">let </span>num = num.to_string();
|
||||
<span class="kw">let </span>arg = <span class="kw">if </span>flags.group {
|
||||
group_num(<span class="kw-2">&</span>num)
|
||||
} <span class="kw">else </span>{
|
||||
Cow::Borrowed(num.as_str())
|
||||
};
|
||||
<span class="kw">let </span>prefix = <span class="kw">if </span>flags.sign {
|
||||
<span class="string">"+"
|
||||
</span>} <span class="kw">else if </span>flags.space {
|
||||
<span class="string">" "
|
||||
</span>} <span class="kw">else </span>{
|
||||
<span class="string">""
|
||||
</span>};
|
||||
<span class="kw">let </span>extended = <span class="macro">format!</span>(
|
||||
<span class="string">"{prefix}{arg:0>precision$}"</span>,
|
||||
precision = precision.unwrap_or(<span class="number">0</span>)
|
||||
);
|
||||
pad_and_print(<span class="kw-2">&</span>extended, flags.left, width, padding_char);
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Prints an unsigned integer value based on the provided flags, width, and precision.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `num` - The unsigned integer value to be printed.
|
||||
/// * `flags` - A reference to the Flags struct containing formatting flags.
|
||||
/// * `width` - The width of the field for the printed unsigned integer.
|
||||
/// * `precision` - An Option containing the precision value.
|
||||
/// * `padding_char` - The padding character as determined by `determine_padding_char`.
|
||||
</span><span class="kw">fn </span>print_unsigned(
|
||||
num: u64,
|
||||
flags: <span class="kw-2">&</span>Flags,
|
||||
width: usize,
|
||||
precision: <span class="prelude-ty">Option</span><usize>,
|
||||
padding_char: Padding,
|
||||
) {
|
||||
<span class="kw">let </span>num = num.to_string();
|
||||
<span class="kw">let </span>s = <span class="kw">if </span>flags.group {
|
||||
group_num(<span class="kw-2">&</span>num)
|
||||
} <span class="kw">else </span>{
|
||||
Cow::Borrowed(num.as_str())
|
||||
};
|
||||
<span class="kw">let </span>s = <span class="macro">format!</span>(<span class="string">"{s:0>precision$}"</span>, precision = precision.unwrap_or(<span class="number">0</span>));
|
||||
pad_and_print(<span class="kw-2">&</span>s, flags.left, width, padding_char);
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Prints an unsigned octal integer value based on the provided flags, width, and precision.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `num` - The unsigned octal integer value to be printed.
|
||||
/// * `flags` - A reference to the Flags struct containing formatting flags.
|
||||
/// * `width` - The width of the field for the printed unsigned octal integer.
|
||||
/// * `precision` - An Option containing the precision value.
|
||||
/// * `padding_char` - The padding character as determined by `determine_padding_char`.
|
||||
</span><span class="kw">fn </span>print_unsigned_oct(
|
||||
num: u32,
|
||||
flags: <span class="kw-2">&</span>Flags,
|
||||
width: usize,
|
||||
precision: <span class="prelude-ty">Option</span><usize>,
|
||||
padding_char: Padding,
|
||||
) {
|
||||
<span class="kw">let </span>prefix = <span class="kw">if </span>flags.alter { <span class="string">"0" </span>} <span class="kw">else </span>{ <span class="string">"" </span>};
|
||||
<span class="kw">let </span>s = <span class="macro">format!</span>(
|
||||
<span class="string">"{prefix}{num:0>precision$o}"</span>,
|
||||
precision = precision.unwrap_or(<span class="number">0</span>)
|
||||
);
|
||||
pad_and_print(<span class="kw-2">&</span>s, flags.left, width, padding_char);
|
||||
}
|
||||
|
||||
<span class="doccomment">/// Prints an unsigned hexadecimal integer value based on the provided flags, width, and precision.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `num` - The unsigned hexadecimal integer value to be printed.
|
||||
/// * `flags` - A reference to the Flags struct containing formatting flags.
|
||||
/// * `width` - The width of the field for the printed unsigned hexadecimal integer.
|
||||
/// * `precision` - An Option containing the precision value.
|
||||
/// * `padding_char` - The padding character as determined by `determine_padding_char`.
|
||||
</span><span class="kw">fn </span>print_unsigned_hex(
|
||||
num: u64,
|
||||
flags: <span class="kw-2">&</span>Flags,
|
||||
width: usize,
|
||||
precision: <span class="prelude-ty">Option</span><usize>,
|
||||
padding_char: Padding,
|
||||
) {
|
||||
<span class="kw">let </span>prefix = <span class="kw">if </span>flags.alter { <span class="string">"0x" </span>} <span class="kw">else </span>{ <span class="string">"" </span>};
|
||||
<span class="kw">let </span>s = <span class="macro">format!</span>(
|
||||
<span class="string">"{prefix}{num:0>precision$x}"</span>,
|
||||
precision = precision.unwrap_or(<span class="number">0</span>)
|
||||
);
|
||||
pad_and_print(<span class="kw-2">&</span>s, flags.left, width, padding_char);
|
||||
}
|
||||
|
||||
<span class="kw">impl </span>Stater {
|
||||
<span class="kw">fn </span>generate_tokens(format_str: <span class="kw-2">&</span>str, use_printf: bool) -> UResult<Vec<Token>> {
|
||||
<span class="kw">let </span><span class="kw-2">mut </span>tokens = Vec::new();
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user