use std::io::Read;
use crate::{
Result, Rudof,
errors::{DataError, ShExError},
formats::{InputSpec, ShapeMapFormat},
types::Data,
utils::get_base_iri,
};
use rudof_iri::IriS;
use rudof_rdf::rdf_core::Rdf;
use shex_ast::{ShapeMapParser, shapemap::QueryShapeMap};
use shex_validation::Validator as ShExValidator;
pub fn load_shapemap(
rudof: &mut Rudof,
shapemap: &InputSpec,
shapemap_format: Option<&ShapeMapFormat>,
base_nodes: Option<&str>,
base_shapes: Option<&str>,
) -> Result<()> {
let (shapemap_format, base_nodes, base_shapes) = init_defaults(rudof, shapemap_format, base_nodes, base_shapes)?;
let (data, shex_validator) = validate_loaded_data_and_schema(rudof)?;
match shapemap_format {
ShapeMapFormat::Compact => {
let shapemap = read_shapemap_compact(shapemap, data, shex_validator, base_nodes, base_shapes)?;
rudof.shapemap = Some(shapemap);
},
_ => {
todo!("ShapeMap format {:?} not yet implemented", shapemap_format);
},
}
Ok(())
}
fn init_defaults(
rudof: &mut Rudof,
shapemap_format: Option<&ShapeMapFormat>,
base_nodes: Option<&str>,
base_shapes: Option<&str>,
) -> Result<(ShapeMapFormat, IriS, IriS)> {
let base_nodes = get_base_iri(rudof, base_nodes)?;
let base_shapes = get_base_iri(rudof, base_shapes)?;
Ok((shapemap_format.copied().unwrap_or_default(), base_nodes, base_shapes))
}
fn validate_loaded_data_and_schema(rudof: &mut Rudof) -> Result<(&mut Data, &ShExValidator)> {
let data = rudof.data.as_mut().ok_or(Box::new(DataError::NoDataLoaded))?;
if !data.is_rdf() {
Err(Box::new(DataError::NoRdfDataLoaded))?
}
let shex_validator = rudof.shex_validator.as_ref().ok_or(ShExError::NoShExSchemaLoaded)?;
Ok((data, shex_validator))
}
fn read_shapemap_compact(
shapemap: &InputSpec,
data: &mut Data,
shex_validator: &ShExValidator,
base_nodes: IriS,
base_shapes: IriS,
) -> Result<QueryShapeMap> {
let mut shapemap_reader = shapemap
.open_read(None, "ShapeMap data")
.map_err(|error| ShExError::DataSourceSpec {
message: format!("Failed to open shapemap source '{}': {error}", shapemap.source_name()),
})?;
let mut v = Vec::new();
shapemap_reader
.read_to_end(&mut v)
.map_err(|error| ShExError::DataSourceSpec {
message: format!("Failed to read shapemap source '{}': {error}", shapemap.source_name()),
})?;
let shapemap_string = String::from_utf8(v).map_err(|error| ShExError::DataSourceSpec {
message: format!("Failed to read shapemap source '{}': {error}", shapemap.source_name()),
})?;
let shapemap = ShapeMapParser::parse(
shapemap_string.as_str(),
&Some(data.unwrap_rdf_mut().prefixmap().unwrap_or_default()),
&Some(base_nodes),
&Some(shex_validator.shapes_prefixmap()),
&Some(base_shapes),
)
.map_err(|e| ShExError::FailedParsingShapeMap {
source_name: shapemap.source_name().to_string(),
error: e.to_string(),
})?;
Ok(shapemap)
}