How to fix compilation error? serde streaming

I get error:

error[E0277]: the trait bound `serde_json::Deserializer<serde_json::de::IoRead<std::io::BufReader<R>>>: api::_::_serde::Deserializer<'_>` is not satisfied
  --> pivot/src/json_source.rs:73:51
   |
73 |         let data: Data = match loader.deserialize(deserializer) {
   |                                                   ^^^^^^^^^^^^ the trait `api::_::_serde::Deserializer<'_>` is not implemented for `serde_json::Deserializer<serde_json::de::IoRead<std::io::BufReader<R>>>`
   |
   = help: the following implementations were found:
             <&'a mut serde_json::Deserializer<R> as api::_::_serde::Deserializer<'de>>

when compiling code:

use crate::infer_json_schema::{infer_json_schema, ArrayProcessor};
use crate::table::Table;
use crate::{PivotEngine, PivotError, TableDefRef};
use serde::de::{self, DeserializeSeed};
use serde::Deserializer;
use std::io::{BufReader, Read, Seek};
use std::sync::{Arc, RwLock};

impl PivotEngine {
    pub fn load_json<R: Read + Seek>(&mut self, name: &str, input: R) -> Result<usize, PivotError> {
        let mut reader = BufReader::new(input);

        struct JsonLoader<'de, R> {
            reader: &'de mut R,
            name: &'de str,
            table_id: u32,
        }

        struct Data {
            schema: TableDefRef,
            table: Table,
            row_num: usize,
        }

        impl<'de, R> DeserializeSeed<'de> for JsonLoader<'de, R>
        where
            R: Read + Seek,
        {
            type Value = Data;

            fn deserialize<D>(
                self,
                deserializer: D,
            ) -> Result<Self::Value, <D as Deserializer<'de>>::Error>
            where
                D: Deserializer<'de>,
            {
                let schema_def = match infer_json_schema(self.reader, self.name, Some(10)) {
                    Ok(t) => t,
                    Err(e) => return Err(de::Error::custom(e.to_string())),
                };
                let schema = Arc::new(RwLock::new(schema_def));

                let table_id = self.table_id;
                let table = Table::new(schema.clone(), table_id);
                let mut row_num = 0;

                let visitor = ArrayProcessor {
                    phase: "making table",
                    consume: move |record| {
                        for (k, v) in record.iter() {
                            // TODO add field
                        }
                        row_num += 1;
                    },
                };
                deserializer.deserialize_seq(visitor)?;

                Ok(Data {
                    schema,
                    table,
                    row_num,
                })
            }
        }

        let deserializer = serde_json::Deserializer::from_reader(reader);
        let loader = JsonLoader {
            reader: &mut reader,
            name,
            table_id: self.tables.len() as u32,
        };
        let data: Data = match loader.deserialize(deserializer) {
            Ok(t) => t,
            Err(e) => return Err(PivotError::Parse(e.to_string())),
        };

        self.schema
            .write()
            .unwrap()
            .tables
            .push(data.schema.clone());
        self.tables.push(Arc::new(RwLock::new(data.table)));
        Ok(data.row_num)
    }
}

Any help appreciated. Thanks!

I am thinking to try StreamDeserializer skipping "[" at the beginning to simplify code

73 | let data: Data = match loader.deserialize(deserializer) {
   |                                           ^^^^^^^^^^^^
              the trait `serde::Deserializer<'_>` is not implemented for
              `serde_json::Deserializer<serde_json::de::IoRead<std::io::BufReader<R>>>`

This is accurate -- on serde_json::Deserializer - Rust it shows the serde::Deserializer impl is for &mut serde_json::Deserializer<R>. If loader.deserialize requires an argument that implements serde::Deserialize then you would need to pass &mut deserializer.

@dtolnay thanks. error message confused me :smile:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.