为自定义& [u8]类型实现FromStr [英] Implementing FromStr for a custom &[u8] type

查看:70
本文介绍了为自定义& [u8]类型实现FromStr的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是两部分的.

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

Ideally I'd like to implement the FromStr trait, but with or without that, I need to implement from_str().

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

A CqlString consists of a u16 (two u8s) followed by the raw bytes of the original string.

下面的版本生成错误:'字节'寿命不足",因此是问题1.如果我将其设置为"impl FromStr for CqlString",则将收到以下错误信息:错误:方法 from_str 的特征类型不兼容:预期的混凝土寿命,找到了约束寿命参数[E0053]

The version below generates "error: 'bytes' does not live long enough", so that's problem #1. If I make it "impl FromStr for CqlString", then I get an earlier error of: error: method from_str has an incompatible type for trait: expected concrete lifetime, found bound lifetime parameter [E0053]

因此,鉴于CqlString的结构,如何正确实现FromStr fn?

So given the structure of CqlString, how can I implement a FromStr fn properly?

#[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)
    }
}

推荐答案

简短的答案是你做不到. CqlString 包含对其他数据的引用,但是 FromStr 希望创建一个完全拥有的对象,该对象不再需要引用& str .这两个概念是不兼容的.

The short answer is that you can't. CqlString contains a reference to other data, but FromStr expects to create a fully-owned object that no longer needs to reference the &str. These two concepts are incompatible.

我能看到的最接近的是,您可以创建一个 OwnedCqlString :

The closest I can see is that you could create an 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();
}

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

Ultimately, this comes down to two questions:

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

一个替代主意

如果您不需要存储字节片,而是可以有一个流"接口,则可以直接在& 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
}

这篇关于为自定义&amp; [u8]类型实现FromStr的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆