1use crate::error::Error;
2use crate::read_impl::read_from_file;
3use std::fs::File;
4use std::io::{Read, Seek};
5
6use crate::error::Error::{InvalidFileExtension, NoFileExtension};
7use crate::validate_impl::validate_from_reader;
8use crate::{FILE_EXTENSION_CITYGML_GML_FORMAT, FILE_EXTENSION_CITYGML_XML_FORMAT};
9use ecitygml_core::model::city_model::CitygmlModel;
10use std::path::Path;
11
12#[derive(Debug, Clone)]
15pub struct CitygmlReader<R: Read + Seek> {
16 reader: R,
17}
18
19impl<R: Read + Seek> CitygmlReader<R> {
20 pub fn new(reader: R) -> Self {
22 Self { reader }
23 }
24
25 pub fn validate(self) -> Result<crate::validate::report::Report, Error> {
26 validate_from_reader(self.reader)
27 }
28
29 pub fn finish(self) -> Result<CitygmlModel, Error> {
30 read_from_file(self.reader)
31 }
32}
33
34impl CitygmlReader<File> {
35 pub fn from_path(path: impl AsRef<Path>) -> Result<Self, Error> {
36 let extension = path.as_ref().extension().ok_or(NoFileExtension())?;
37 if extension != FILE_EXTENSION_CITYGML_GML_FORMAT
38 && extension != FILE_EXTENSION_CITYGML_XML_FORMAT
39 {
40 return Err(InvalidFileExtension(
41 extension.to_str().unwrap_or_default().to_string(),
42 ));
43 }
44
45 let file = std::fs::File::open(path)?;
46 Ok(Self::new(file))
47 }
48}