#![allow(dead_code)]
use std::sync::Arc;
use crate::convert::{DistTargetFormat, TextEmission};
use crate::model::MulticonductorNetwork;
#[derive(Debug)]
pub(crate) struct Parsed {
pub warnings: Vec<String>,
pub diagnostics: Vec<crate::diagnostics::Diagnostic>,
pub source: Option<Arc<String>>,
pub module: powerio_core::PioModule<MulticonductorNetwork>,
network: MulticonductorNetwork,
}
impl std::ops::Deref for Parsed {
type Target = MulticonductorNetwork;
fn deref(&self) -> &MulticonductorNetwork {
&self.network
}
}
impl std::ops::DerefMut for Parsed {
fn deref_mut(&mut self) -> &mut MulticonductorNetwork {
&mut self.network
}
}
impl Parsed {
pub fn emit(&self, target: DistTargetFormat) -> TextEmission {
crate::convert::emit_text_with_options(
&self.module,
target,
&crate::convert::EmitOptions::default(),
)
.expect("fixture supports the requested conversion")
}
pub fn emit_value(&self, target: DistTargetFormat) -> TextEmission {
crate::convert::emit_value_text(&self.network, target)
}
}
fn from_module(module: powerio_core::PioModule<MulticonductorNetwork>) -> Parsed {
let source = module.source().and_then(|source| {
let buffer = source.primary_buffer().ok()?;
let text = std::str::from_utf8(buffer.content_bytes()).ok()?;
Some(Arc::new(text.to_owned()))
});
Parsed {
warnings: crate::diagnostics::render_diagnostics(module.diagnostics()),
diagnostics: module.diagnostics().to_vec(),
source,
network: module.value().clone(),
module,
}
}
fn declared(
source: powerio_core::Source,
from: Option<&str>,
) -> Result<powerio_core::Source, crate::Error> {
match from {
None => Ok(source),
Some(token) => {
if crate::convert::parse_dist_target_format(token).is_none() {
return Err(crate::Error::UnknownFormat(token.to_string()));
}
let id = powerio_core::FormatId::new(token.to_ascii_lowercase().replace('_', "-"))
.map_err(|_| crate::Error::UnknownFormat(token.to_string()))?;
Ok(source.with_format(id))
}
}
}
fn core_to_dist(error: &powerio_core::Error) -> crate::Error {
crate::Error::FormatRead {
format: "case text",
message: error.to_string(),
}
}
pub(crate) fn parse_str(text: &str, from: &str) -> crate::Result<Parsed> {
let source = declared(
powerio_core::Source::from_memory("<memory>", text.as_bytes().to_vec())
.map_err(|error| core_to_dist(&error))?,
Some(from),
)?;
crate::convert::parse(source)
.map(from_module)
.map_err(|error| core_to_dist(&error))
}
pub(crate) fn parse_file(
path: impl AsRef<std::path::Path>,
from: Option<&str>,
) -> crate::Result<Parsed> {
if let Some(token) = from
&& crate::convert::parse_dist_target_format(token).is_none()
{
return Err(crate::Error::UnknownFormat(token.to_string()));
}
let source = declared(
powerio_core::Source::open(path.as_ref()).map_err(|error| core_to_dist(&error))?,
from,
)?;
crate::convert::parse(source)
.map(from_module)
.map_err(|error| core_to_dist(&error))
}
pub(crate) fn parse_dss_str(text: &str) -> Parsed {
parse_str(text, "dss").expect("dss text parses without a filesystem")
}
pub(crate) fn parse_dss_file(path: impl AsRef<std::path::Path>) -> crate::Result<Parsed> {
parse_file(path, Some("dss"))
}
pub(crate) fn parse_bmopf_str(text: &str) -> crate::Result<Parsed> {
parse_str(text, "bmopf-json")
}
pub(crate) fn parse_pmd_str(text: &str) -> crate::Result<Parsed> {
parse_str(text, "pmd-json")
}