use crate::{GlobalArgs, Subcommand};
use anyhow::Context;
use clap::{Parser, ValueEnum};
use slumber_import::ImportInput;
use std::{
fs::File,
io::{self, Write},
path::PathBuf,
process::ExitCode,
str::FromStr,
};
use tracing::info;
#[derive(Clone, Debug, Parser)]
#[expect(rustdoc::bare_urls)]
pub struct ImportCommand {
format: Format,
#[clap(value_parser = ImportInput::from_str)]
input: ImportInput,
output_file: Option<PathBuf>,
}
#[derive(Copy, Clone, Debug, ValueEnum)]
enum Format {
Insomnia,
Openapi,
#[value(alias = "vscode", alias = "jetbrains")]
Rest,
V3,
}
impl Subcommand for ImportCommand {
async fn execute(self, _global: GlobalArgs) -> anyhow::Result<ExitCode> {
info!(
input = ?self.input, format = ?self.format, "Importing collection"
);
let collection = match self.format {
Format::Insomnia => {
slumber_import::from_insomnia(&self.input).await?
}
Format::Openapi => {
slumber_import::from_openapi(&self.input).await?
}
Format::Rest => slumber_import::from_rest(&self.input).await?,
Format::V3 => slumber_import::from_v3(&self.input).await?,
};
let mut writer: Box<dyn Write> = match self.output_file {
Some(output_file) => Box::new(
File::options()
.create(true)
.truncate(true)
.write(true)
.open(&output_file)
.context(format!(
"Error opening collection output file \
`{}`",
output_file.display()
))?,
),
None => Box::new(io::stdout()),
};
serde_yaml::to_writer(&mut writer, &collection)
.context(format!("Error loading collection from {}", self.input))?;
Ok(ExitCode::SUCCESS)
}
}