1use crate::conversions::Converter;
2use crate::io::Error::CannotReadFile;
3use crate::{Error, Output, Result};
4use gesha_collections::yaml::YamlMap;
5use openapi_types::yaml::{ToOpenApi, load_from_str};
6use std::fmt::Debug;
7use std::fs;
8use std::path::PathBuf;
9use tracing::instrument;
10
11#[derive(Debug)]
12pub struct Reader {
13 path: PathBuf,
14}
15
16impl Reader {
17 pub fn new(path: impl Into<PathBuf>) -> Self {
18 Self { path: path.into() }
19 }
20
21 #[instrument]
22 pub fn open_target_type<A>(&self, converter: &A) -> Result<Output<A::TargetType>>
23 where
24 A: Converter + Debug,
25 {
26 let mut errors = vec![];
27 let yaml = self.as_yaml_map()?;
28 let (from, errors_of_openapi) = ToOpenApi::apply(yaml).into_tuple();
29 errors.append(
30 &mut errors_of_openapi
31 .into_iter()
32 .map(Error::openapi(&self.path))
33 .collect(),
34 );
35
36 let (to, errors_of_conversion) = converter
37 .convert(from)
38 .map_err(Error::conversion(&self.path))?
39 .into_tuple();
40
41 errors.append(
42 &mut errors_of_conversion
43 .into_iter()
44 .map(Error::conversion(&self.path))
45 .collect(),
46 );
47
48 Ok(Output::new(to, errors))
49 }
50
51 pub(crate) fn as_string(&self) -> Result<String> {
52 let content = fs::read_to_string(&self.path).map_err(|cause| CannotReadFile {
53 path: PathBuf::from(&self.path),
54 detail: format!("{:?}", cause),
55 })?;
56 Ok(content)
57 }
58
59 fn as_yaml_map(&self) -> Result<YamlMap> {
60 let content = self.as_string()?;
61 let map = load_from_str(&content).map_err(Error::openapi(&self.path))?;
62 Ok(map)
63 }
64}