Serialization 围绕固定大小向量实现包装器的可解码

Serialization 围绕固定大小向量实现包装器的可解码,serialization,rust,Serialization,Rust,背景:序列化板条箱未记录,派生可解码文件不起作用。我还研究了其他类型的现有实现,发现代码很难遵循 解码过程是如何工作的,我如何为这个结构实现可解码的 pub struct Grid<A> { data: [[A,..GRIDW],..GRIDH] } 在Decodable::decode(d) 错误:未能找到trait的实现 serialize::serialize::可解码的[[A,…20],…20] 由于各种原因,目前不可能很好地做到这一点: 我们不能在固定长度数组的

背景:序列化板条箱未记录,派生可解码文件不起作用。我还研究了其他类型的现有实现,发现代码很难遵循

解码过程是如何工作的,我如何为这个结构实现可解码的

pub struct Grid<A> {
    data: [[A,..GRIDW],..GRIDH]
}
Decodable::decode(d)

错误:未能找到trait的实现 serialize::serialize::可解码的[[A,…20],…20]


由于各种原因,目前不可能很好地做到这一点:

  • 我们不能在固定长度数组的长度上通用(基本问题)
  • 当前的trait一致性限制意味着我们不能用[a,…GRIDW](还有一个用于
    GRIDH
    )的
    impl-MyDecodable来编写自定义
    trait-MyDecodable{…}
    )和一个整体实现
    impl

    通过使用来实例化每个版本,还可以编写一个更“通用”的
    [T,…n]
    解码器,并对递归解码的处理方式进行特殊控制,以允许处理嵌套的固定长度数组(如
    网格所需);这需要更少的代码(尤其是具有更多层或各种不同长度的代码),但宏解决方案:

    • 可能更难理解,而且
    • 我给出的方法可能效率较低(为每个固定长度数组创建了一个新的
      array
      变量,包括新的
      Default
      s,而上面的非宏解决方案只使用一个
      array
      ,因此对网格中的每个元素只调用一次
      Default::Default
      )。可以扩展到一组类似的递归循环,但我不确定

    最简单的方法往往是“将定义更改为有效的定义,使用
    --非常扩展的
    获得该定义,然后进行调整以适应新形式”。@ChrisMorgan我根本不知道如何将其调整为新形式。@A.B.您试图反序列化的JSON字符串是什么?-下面是几个JSON反序列化的例子。这能处理JSON吗?这可能是一个愚蠢的问题,但JSON不需要在尝试读取序列之前读取结构名称和数据字段吗?@a.B.噢,哎呀;我已经计划好了(为什么我有一个单独的函数),但是忘记了正确地实现它。现在修好了。
    
    impl <A: Decodable<D, E>, D: Decoder<E>, E> Decodable<D, E> for Grid<A> {
        fn decode(decoder: &mut D) -> Result<Grid<A>, E> {
            decoder.read_struct("Grid", 1u, ref |d| Ok(Grid {
                data: match d.read_struct_field("data", 0u, ref |d| Decodable::decode(d)) {
                    Ok(e) => e,
                    Err(e) => return Err(e)
                },
            }))
        }
    }
    
    extern crate serialize;
    
    use std::default::Default;
    use serialize::{Decoder, Decodable};
    
    static GRIDW: uint = 10;
    static GRIDH: uint = 5;
    
    
    fn decode_grid<E, D: Decoder<E>,
                   A: Copy + Default + Decodable<D, E>>(d: &mut D) 
            -> Result<Grid<A>, E> {
        // mirror the Vec implementation: try to read a sequence
        d.read_seq(|d, len| {
            // check it's the required length
            if len != GRIDH {
                return Err(
                    d.error(format!("expecting length {} but found {}", 
                                    GRIDH, len).as_slice()));
            }
            // create the array with empty values ...
            let mut array: [[A, .. GRIDW], .. GRIDH] 
                = [[Default::default(), .. GRIDW], .. GRIDH];
    
            // ... and fill it in progressively ...
            for (i, outer) in array.mut_iter().enumerate() {
                // ... by reading each outer element ... 
                try!(d.read_seq_elt(i, |d| {
                    //  ... as a sequence ...
                    d.read_seq(|d, len| {
                        // ... of the right length,
                        if len != GRIDW { return Err(d.error("...")) }
    
                        // and then read each element of that sequence as the
                        // elements of the grid.
                        for (j, inner) in outer.mut_iter().enumerate() {
                            *inner = try!(d.read_seq_elt(j, Decodable::decode));
                        }
                        Ok(())
                    })
                }));
            }
    
            // all done successfully!
            Ok(Grid { data: array })
        })
    }
    
    
    pub struct Grid<A> {
        data: [[A,..GRIDW],..GRIDH]
    }
    
    impl<E, D: Decoder<E>, A: Copy + Default + Decodable<D, E>> 
        Decodable<D, E> for Grid<A> {
        fn decode(d: &mut D) -> Result<Grid<A>, E> {
            d.read_struct("Grid", 1, |d| {
                d.read_struct_field("data", 0, decode_grid)
            })
        }
    }
    
    fn main() {}