alpm_srcinfo/
commands.rs

1//! Functions called from the binary.
2use std::{
3    io::{self, IsTerminal},
4    path::PathBuf,
5};
6
7use alpm_common::MetadataFile;
8use alpm_types::Architecture;
9
10use crate::{
11    SourceInfo,
12    SourceInfoSchema,
13    cli::OutputFormat,
14    error::Error,
15    source_info::v1::merged::MergedPackage,
16};
17
18/// Validates a SRCINFO file from a path or stdin.
19///
20/// Wraps the [`parse`] function and allows to ensure that no errors occurred during parsing.
21pub fn validate(file: Option<&PathBuf>, schema: Option<SourceInfoSchema>) -> Result<(), Error> {
22    let _result = parse(file, schema)?;
23
24    Ok(())
25}
26
27/// Parses a SRCINFO file from a path or stdin and outputs it in the specified format on stdout.
28///
29/// # Errors
30///
31/// Returns an error if the input can not be parsed and validated, or if the output can not be
32/// formatted in the selected output format.
33pub fn format_packages(
34    file: Option<&PathBuf>,
35    schema: Option<SourceInfoSchema>,
36    output_format: OutputFormat,
37    architecture: Architecture,
38    pretty: bool,
39) -> Result<(), Error> {
40    let srcinfo = parse(file, schema)?;
41    let SourceInfo::V1(source_info) = srcinfo;
42
43    let packages: Vec<MergedPackage> = source_info
44        .packages_for_architecture(architecture)
45        .collect();
46
47    match output_format {
48        OutputFormat::Json => {
49            let json = if pretty {
50                serde_json::to_string_pretty(&packages)?
51            } else {
52                serde_json::to_string(&packages)?
53            };
54            println!("{json}");
55        }
56    }
57
58    Ok(())
59}
60
61/// Parses and interprets a SRCINFO file from a path or stdin.
62///
63/// ## Note
64///
65/// If a command is piped to this process, the input is read from stdin.
66/// See [`IsTerminal`] for more information about how terminal detection works.
67///
68/// [`IsTerminal`]: https://doc.rust-lang.org/stable/std/io/trait.IsTerminal.html
69///
70/// # Errors
71///
72/// Returns an error if the input can not be parsed and validated, or if the output can not be
73/// formatted in the selected output format.
74///
75/// Furthermore, returns an error array with potentially un/-recoverable (linting-)errors, which
76/// needs to be explicitly handled by the caller.
77pub fn parse(
78    file: Option<&PathBuf>,
79    schema: Option<SourceInfoSchema>,
80) -> Result<SourceInfo, Error> {
81    if let Some(file) = file {
82        SourceInfo::from_file_with_schema(file, schema)
83    } else if !io::stdin().is_terminal() {
84        SourceInfo::from_stdin_with_schema(schema)
85    } else {
86        return Err(Error::NoInputFile);
87    }
88}