use crate::{
builder::{self, Convert},
crypto::PublicKey,
datalog::{Check, Fact, Rule, SymbolTable, Term},
error,
};
use super::{public_keys::PublicKeys, Scope};
#[derive(Clone, Debug)]
pub struct Block {
pub symbols: SymbolTable,
pub facts: Vec<Fact>,
pub rules: Vec<Rule>,
pub checks: Vec<Check>,
pub context: Option<String>,
pub version: u32,
pub external_key: Option<PublicKey>,
pub public_keys: PublicKeys,
pub scopes: Vec<Scope>,
}
impl Block {
pub fn symbol_add(&mut self, s: &str) -> Term {
self.symbols.add(s)
}
pub fn symbol_insert(&mut self, s: &str) -> u64 {
self.symbols.insert(s)
}
pub(crate) fn print_source(&self, symbols: &SymbolTable) -> String {
let facts: Vec<_> = self.facts.iter().map(|f| symbols.print_fact(f)).collect();
let rules: Vec<_> = self
.rules
.iter()
.map(|rule| symbols.print_rule(rule))
.collect();
let checks: Vec<_> = self
.checks
.iter()
.map(|check| symbols.print_check(check))
.collect();
let mut res = facts.join(";\n");
if !facts.is_empty() {
res.push_str(";\n");
}
res.push_str(&rules.join(";\n"));
if !rules.is_empty() {
res.push_str(";\n");
}
res.push_str(&checks.join(";\n"));
if !checks.is_empty() {
res.push_str(";\n");
}
res
}
pub(crate) fn translate(
&self,
from_symbols: &SymbolTable,
to_symbols: &mut SymbolTable,
) -> Result<Self, error::Format> {
Ok(Block {
symbols: SymbolTable::new(),
facts: self
.facts
.iter()
.map(|f| {
builder::Fact::convert_from(f, from_symbols).map(|f| f.convert(to_symbols))
})
.collect::<Result<Vec<Fact>, error::Format>>()?,
rules: self
.rules
.iter()
.map(|r| {
builder::Rule::convert_from(r, from_symbols).map(|r| r.convert(to_symbols))
})
.collect::<Result<Vec<Rule>, error::Format>>()?,
checks: self
.checks
.iter()
.map(|c| {
builder::Check::convert_from(c, from_symbols).map(|c| c.convert(to_symbols))
})
.collect::<Result<Vec<Check>, error::Format>>()?,
context: self.context.clone(),
version: self.version,
external_key: self.external_key,
public_keys: self.public_keys.clone(),
scopes: self
.scopes
.iter()
.map(|s| {
builder::Scope::convert_from(s, from_symbols).map(|s| s.convert(to_symbols))
})
.collect::<Result<Vec<Scope>, error::Format>>()?,
})
}
}