使用特征对象实现可变的树结构

时间:2019-07-31 13:30:31

标签: rust traits

我正在尝试在Rust中实现树结构。我的结构就像一个JSON对象,其中属性可以是其他JSON对象的简单值或子树。

对于叶子,我有一个名为ShyScalar的枚举:

#[derive(Clone, PartialEq, Debug)]
pub enum ShyScalar {
    Boolean(bool),
    Integer(i64),
    Rational(f64),
    String(String),
    Error(String)
}

对于节点,我正在尝试创建另一个枚举ShyValue。它可以是Scalar(ShyScalar)Object,我正在尝试弄清楚如何实现Object部分。它的核心是特征ShyAssociation,它使我可以使用字符串名称(粗略的反射形式)获取或设置属性。这是ShyAssociation特质实现的一部分,其中有一个使用HashMap的示例实现。

pub trait ShyAssociation<'a> {
    /// Set the named property to a new value and return the previous value.
    /// If it is not permitted to set this property or it had no value previously, return None.
    fn set(&mut self, property_name: &'a str, property_value: ShyValue) -> Option<ShyValue>;

    /// Get the value of the named property.
    /// If the property has no value or the property does not exist, return None.
    fn get(&self, property_name: &'a str) -> Option<&ShyValue>;

    /// True if is is possible to set the named property. 
    /// This may be true even if the property does not currently have a value.
    fn can_set_property(&self, property_name: &'a str) -> bool;

    /// True if the property currently has a value that can be retrieved, false otherwise.
    fn can_get_property(&self, property_name: &'a str) -> bool;
}

impl<'a> ShyAssociation<'a> for HashMap<&'a str, ShyValue> {
    fn set(&mut self, property_name: &'a str, property_value: ShyValue) -> Option<ShyValue> {
        self.insert(property_name, property_value)
    }

    fn get(&self, property_name: &'a str) -> Option<&ShyValue> {
        HashMap::get(self, property_name)
    }

    fn can_set_property(&self, _property_name: &'a str) -> bool {
        true
    }

    fn can_get_property(&self, property_name: &'a str) -> bool {
        self.contains_key(property_name)
    }
}

此方法在ShyValue包含Object变体之前起作用。

我尝试使用Box,并且正在研究RcRefCell,但不知道如何编写内容,以便能够实现{{1}的三个基本特征}:ObjectClonePartialEq

如果我使用objekt crate就能实现Debug的工作,而How to clone a struct storing a boxed trait object?实现了https://element.eleme.io/#/en-US/component/checkbox的想法。

我无法弄清楚如何组成东西来实现所有三个特征。


我要解决的更大问题是为规则引擎构建上下文对象(符号表)。我需要能够提供实现Clone的任意对象,以允许规则引擎使用点表示法提取值并将结果设置回对象中。我正在努力解决Rust不支持反射的事实。


其他信息。

当我使用objekt_clonable板条箱并尝试与PartialEq和Debug组合时,出现以下错误:

  

无法建立特征ShyAssociation   变成物体

     

无法建立特征parser::shy_association::ShyAssociation   变成物体

     

注意:特征不能使用parser::shy_association::ShyAssociation作为类型参数   超级特征或where-clausesrustc(E0038)   <:: objekt :: macros :: __ internal_clone_trait_object宏>(38,55):the   特质Self不能设为   对象

以下是我使用的一些代码:

parser::shy_association::ShyAssociation

0 个答案:

没有答案
相关问题