biscuit_auth/token/builder/
predicate.rs

1/*
2 * Copyright (c) 2019 Geoffroy Couprie <contact@geoffroycouprie.com> and Contributors to the Eclipse Foundation.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5use std::fmt;
6
7use crate::{
8    datalog::{self, SymbolTable},
9    error,
10};
11
12use super::{Convert, Term};
13
14/// Builder for a Datalog predicate, used in facts and rules
15#[derive(Debug, Clone, PartialEq, Hash, Eq)]
16pub struct Predicate {
17    pub name: String,
18    pub terms: Vec<Term>,
19}
20
21impl Predicate {
22    pub fn new<T: Into<Vec<Term>>>(name: String, terms: T) -> Predicate {
23        Predicate {
24            name,
25            terms: terms.into(),
26        }
27    }
28}
29
30impl Convert<datalog::Predicate> for Predicate {
31    fn convert(&self, symbols: &mut SymbolTable) -> datalog::Predicate {
32        let name = symbols.insert(&self.name);
33        let mut terms = vec![];
34
35        for term in self.terms.iter() {
36            terms.push(term.convert(symbols));
37        }
38
39        datalog::Predicate { name, terms }
40    }
41
42    fn convert_from(p: &datalog::Predicate, symbols: &SymbolTable) -> Result<Self, error::Format> {
43        Ok(Predicate {
44            name: symbols.print_symbol(p.name)?,
45            terms: p
46                .terms
47                .iter()
48                .map(|term| Term::convert_from(term, symbols))
49                .collect::<Result<Vec<_>, error::Format>>()?,
50        })
51    }
52}
53
54impl AsRef<Predicate> for Predicate {
55    fn as_ref(&self) -> &Predicate {
56        self
57    }
58}
59
60impl fmt::Display for Predicate {
61    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62        write!(f, "{}(", self.name)?;
63
64        if !self.terms.is_empty() {
65            write!(f, "{}", self.terms[0])?;
66
67            if self.terms.len() > 1 {
68                for i in 1..self.terms.len() {
69                    write!(f, ", {}", self.terms[i])?;
70                }
71            }
72        }
73        write!(f, ")")
74    }
75}
76
77impl From<biscuit_parser::builder::Predicate> for Predicate {
78    fn from(p: biscuit_parser::builder::Predicate) -> Self {
79        Predicate {
80            name: p.name,
81            terms: p.terms.into_iter().map(|t| t.into()).collect(),
82        }
83    }
84}