为自定义& [u8]类型实现FromStr

时间:2014-12-31 16:02:10

标签: rust lifetime

这是一个两个部分。

理想情况下,我想实现FromStr特性,但无论有没有,我都需要实现from_str()。

CqlString由一个u16(两个u8s)组成,后跟原始字符串的原始字节。

以下版本生成“错误:'字节'的活动时间不够长”,因此问题#1。 如果我使它“impl FromStr for CqlString”,那么我得到一个早期的错误: 错误:方法from_str具有特征的不兼容类型:预期的具体生命周期,找到的绑定生存期参数[E0053]

所以考虑到CqlString的结构,我该如何正确实现FromStr fn?

#[repr(C, packed)] 
pub struct CqlString<'a>(&'a [u8]);

impl<'a> CqlString<'a>  {
    fn from_str(s: &str) -> Option<CqlString> {
        let mut bytes = Vec::<u8>::new();
        bytes.push_all(unsafe{Utils::raw_byte_repr(&s.len().to_u16())}); //convert the hashmap length to a a two byte short and start building our &[u8]
        bytes.push_all(s.as_bytes());
        let cqls = CqlString(bytes[]);
        Some(cqls)
    }
}

1 个答案:

答案 0 :(得分:2)

简短的回答是,你不能。 CqlString包含对其他数据的引用,但FromStr期望创建一个不再需要引用&str的全资对象。这两个概念是不相容的。

我能看到的最近的是你可以创建一个OwnedCqlString

struct OwnedCqlString {
    data: Vec<u8>,
}

impl OwnedCqlString {
    fn as_cql_string(&self) -> CqlString { CqlString(self.data.as_slice()) }
}

impl FromStr for OwnedCqlString {
    fn from_str(s: &str) -> Option<OwnedCqlString> {
        // logic here
    }
}

fn main() {
    let ocs: OwnedCqlString = "hello".parse();
    let cs = ocs.as_cql_string();
}

最终,这归结为两个问题:

  1. 您要在哪里存储代表大小的字节?
  2. 如何确保这些字节紧跟在内存中的字符串数据之前?
  3. 另一种想法

    如果你不需要存储切片的字节,而是可以有一个“流”接口,那么你可以直接在&str上实现它:

    trait WriteCqlStr {
        fn write_to<W>(&self, &mut W)
            where W: Writer; 
    }
    
    impl WriteCqlStr for CqlStr {
        // Straight-forward impl, write the bytes we refer to
    }
    
    impl<'a> WriteCqlStr for &'a str {
        // Write the length, then write the bytes of the str
    }