1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
pub mod api;
pub mod pattern_renderer;

use crate::core::model::pins::pin::Resolver;
use crate::core::tester::{TesterAPI, TesterID};
use crate::generator::ast::Node;
use crate::generator::processor::Return;
use crate::utility::differ::{ASCIIDiffer, Differ};
use crate::Result;
use pattern_renderer::Renderer;
use std::path::{Path, PathBuf};

pub trait VectorBased:
    std::fmt::Debug + std::default::Default + crate::core::tester::Interceptor + TesterID + Clone + Send
{
    fn comment_str(&self) -> &str;
    fn file_ext(&self) -> &str;
    fn print_vector(
        &self,
        renderer: &mut pattern_renderer::Renderer,
        repeat: u32,
        compressable: bool,
    ) -> Option<Result<String>>;
    fn print_pinlist(&self, renderer: &mut pattern_renderer::Renderer) -> Option<Result<String>>;

    fn print_pattern_end(
        &self,
        _renderer: &mut pattern_renderer::Renderer,
    ) -> Option<Result<String>> {
        None
    }

    fn pin_action_resolver(&self) -> Option<Resolver> {
        None
    }

    fn override_node(&self, _renderer: &mut Renderer, _node: &Node) -> Option<Result<Return>> {
        None
    }
}

impl<T: 'static> pattern_renderer::RendererAPI for T
where
    T: VectorBased,
{
    default fn file_ext(&self) -> &str {
        VectorBased::file_ext(self)
    }

    default fn comment_str(&self) -> &str {
        VectorBased::comment_str(self)
    }

    default fn print_vector(
        &self,
        renderer: &mut pattern_renderer::Renderer,
        repeat: u32,
        compressable: bool,
    ) -> Option<Result<String>> {
        VectorBased::print_vector(self, renderer, repeat, compressable)
    }

    default fn print_pinlist(
        &self,
        renderer: &mut pattern_renderer::Renderer,
    ) -> Option<Result<String>> {
        VectorBased::print_pinlist(self, renderer)
    }

    default fn print_pattern_end(
        &self,
        renderer: &mut pattern_renderer::Renderer,
    ) -> Option<Result<String>> {
        VectorBased::print_pattern_end(self, renderer)
    }

    fn override_node(&self, renderer: &mut Renderer, node: &Node) -> Option<Result<Return>> {
        VectorBased::override_node(self, renderer, node)
    }
}

impl<T: 'static> TesterAPI for T
where
    T: VectorBased,
{
    default fn render_pattern(&mut self, node: &Node) -> Result<Vec<PathBuf>> {
        pattern_renderer::Renderer::run(self, node)
    }

    default fn pattern_differ(&self, pat_a: &Path, pat_b: &Path) -> Option<Box<dyn Differ>> {
        let mut d = ASCIIDiffer::new(pat_a, pat_b);
        let _ = d.ignore_comments(self.comment_str());
        Some(Box::new(d))
    }

    default fn program_differ(&self, pat_a: &Path, pat_b: &Path) -> Option<Box<dyn Differ>> {
        let mut d = ASCIIDiffer::new(pat_a, pat_b);
        let _ = d.ignore_comments(self.comment_str());
        Some(Box::new(d))
    }

    default fn pin_action_resolver(&self) -> Option<Resolver> {
        VectorBased::pin_action_resolver(self)
    }

    default fn render_program(&mut self) -> crate::Result<Vec<PathBuf>> {
        log_debug!("Tester '{}' does not implement render_program", &self.id());
        Ok(vec![])
    }

    default fn output_dir(&self) -> Result<PathBuf> {
        let dir = crate::STATUS.output_dir().join(&self.name().to_lowercase());
        if !dir.exists() {
            std::fs::create_dir_all(&dir)?;
        }
        Ok(dir)
    }
}