dvcompute_experiment_cons 2.0.1

Discrete event simulation library (support of experiments for conservative distributed simulation)
Documentation
// Copyright (c) 2020-2022  David Sorokin <davsor@mail.ru>, based in Yoshkar-Ola, Russia
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use std::io;
use std::io::*;
use std::path::Path;
use std::result;
use std::fs;
use std::fs::File;

use dvcompute::simulation;

use crate::simulation::experiment::*;
use crate::simulation::utils;
use crate::simulation::utils::html::*;
use crate::simulation::utils::convert::convert_result;

/// It defines the web page rendering.
pub struct WebPageRendering<T> {

    /// The provided parameter.
    pub arg: T,

    /// The experiment file path.
    pub path: Box<Path>
}

/// It replies to the requests made by the web page renderer.
pub trait WebPageWriter {

    /// Write the TOC (Table of Contents) item in the HTML index file
    /// after the finalisation function is called, i.e. in the very end.
    /// The index parameter specifies the ordered number of the item.
    /// You should start the HTML code with call of
    /// the `begin_html_list_item` function.
    fn write_toc_html(&self, w: &mut dyn Write, index: usize) -> io::Result<()>;

    /// Write the HTML code in the index file after the finalisation
    /// function is called. The index parameter specifies the ordered
    /// number of the item.
    fn write_html(&self, w: &mut dyn Write, index: usize) -> io::Result<()>;
}

/// A convenient type synonym for describing the web page generator.
pub type WebPageGenerator<T> = dyn ExperimentGenerator<WebPageRendering<T>>;

impl<T> ExperimentRendering for WebPageRendering<T> {

    type ExperimentContext = Box<dyn WebPageWriter + Send>;

    type ExperimentEnvironment = Box<Path>;

    fn prepare(&self, _experiment: &Experiment) -> simulation::Result<Self::ExperimentEnvironment> {
        utils::path::resolve_file_path(&self.path)
    }

    fn render(&self, experiment: &Experiment, reporters: &Vec<Box<dyn ExperimentReporter<Self> + Sync + Send>>, env: &Self::ExperimentEnvironment) -> simulation::Result<()>
        where Self: Sized
    {
        convert_result(fs::create_dir_all(env))?;
        let mut buf = env.to_path_buf();
        buf.push("index.html");
        let path = buf.into_boxed_path();
        let mut file: File = convert_result(File::create(&path))?;

        convert_result(begin_html_document(&mut file, &experiment.title))?;
        for i in 0 .. reporters.len() {
            let reporter = &reporters[i];
            convert_result(reporter.context().write_toc_html(&mut file, 1 + i))?;
        }
        convert_result(write_html_break(&mut file))?;
        if let Some(description) = &experiment.description {
            convert_result(begin_html_paragraph(&mut file))?;
            convert_result(write_html_text(&mut file, description))?;
            convert_result(end_html_paragraph(&mut file))?;
        }
        for i in 0 .. reporters.len() {
            let reporter = &reporters[i];
            convert_result(reporter.context().write_html(&mut file, 1 + i))?;
        }
        convert_result(end_html_document(&mut file))?;

        if experiment.verbose {
            println!("Generated file {}", path.display());
        }

        result::Result::Ok(())
    }

    fn on_completed(&self, _experiment: &Experiment, _env: &Self::ExperimentEnvironment) -> simulation::Result<()> {
        result::Result::Ok(())
    }

    fn on_failed(&self, _experiment: &Experiment, _env: &Self::ExperimentEnvironment, _err: &simulation::error::Error) -> simulation::Result<()> {
        result::Result::Ok(())
    }
}