rklaehn/banyan-ipfs-camp-2022

Question: Implementing Encode and Decode

Closed this issue · 1 comments

I hate to bug you again, but this is driving me a little nuts. I understand if you're busy, but if you have a moment to look at this I'd appreciate it.

I have this code:
https://gist.github.com/chrisrossi/c8778b51337d40e8b52fb8952cf49084

And am getting this error:

error[E0277]: the trait bound `SimpleRow: libipld_core::codec::Encode<libipld_cbor::DagCborCodec>` is not satisfied
   --> src/simple_example.rs:125:16
    |
125 |     txn.extend(&mut builder, rows);
    |         ------ ^^^^^^^^^^^^ the trait `libipld_core::codec::Encode<libipld_cbor::DagCborCodec>` is not implemented for `SimpleRow`
    |         |
    |         required by a bound introduced by this call
    |
    = help: the following other types implement trait `libipld_core::codec::Encode<C>`:
              <&T as libipld_core::codec::Encode<C>>
              <() as libipld_core::codec::Encode<libipld_cbor::DagCborCodec>>
              <(A, B) as libipld_core::codec::Encode<libipld_cbor::DagCborCodec>>
              <(A, B, C) as libipld_core::codec::Encode<libipld_cbor::DagCborCodec>>
              <(A, B, C, D) as libipld_core::codec::Encode<libipld_cbor::DagCborCodec>>
              <(A,) as libipld_core::codec::Encode<libipld_cbor::DagCborCodec>>
              <Arc<T> as libipld_core::codec::Encode<libipld_cbor::DagCborCodec>>
              <BTreeMap<K, T> as libipld_core::codec::Encode<libipld_cbor::DagCborCodec>>
            and 37 others
    = note: required for `SimpleRow` to implement `libipld_cbor::DagCbor`
    = note: required for `SimpleRow` to implement `BanyanValue`
note: required by a bound in `banyan::tree::<impl Transaction<T, R, W>>::extend`
   --> /home/chris/.cargo/registry/src/github.com-1ecc6299db9ec823/banyan-0.17.1/src/tree.rs:562:12
    |
562 |         V: BanyanValue,
    |            ^^^^^^^^^^^ required by this bound in `banyan::tree::<impl Transaction<T, R, W>>::extend`

error[E0277]: the trait bound `SimpleRow: libipld_core::codec::Decode<libipld_cbor::DagCborCodec>` is not satisfied
   --> src/simple_example.rs:125:16
    |
125 |     txn.extend(&mut builder, rows);
    |         ------ ^^^^^^^^^^^^ the trait `libipld_core::codec::Decode<libipld_cbor::DagCborCodec>` is not implemented for `SimpleRow`
    |         |
    |         required by a bound introduced by this call
    |
    = help: the following other types implement trait `libipld_core::codec::Decode<C>`:
              <() as libipld_core::codec::Decode<libipld_cbor::DagCborCodec>>
              <(A, B) as libipld_core::codec::Decode<libipld_cbor::DagCborCodec>>
              <(A, B, C) as libipld_core::codec::Decode<libipld_cbor::DagCborCodec>>
              <(A, B, C, D) as libipld_core::codec::Decode<libipld_cbor::DagCborCodec>>
              <(A,) as libipld_core::codec::Decode<libipld_cbor::DagCborCodec>>
              <Arc<T> as libipld_core::codec::Decode<libipld_cbor::DagCborCodec>>
              <BTreeMap<K, T> as libipld_core::codec::Decode<libipld_cbor::DagCborCodec>>
              <Box<[u8]> as libipld_core::codec::Decode<libipld_cbor::DagCborCodec>>
            and 33 others
    = note: required for `SimpleRow` to implement `libipld_cbor::DagCbor`
    = note: required for `SimpleRow` to implement `BanyanValue`
note: required by a bound in `banyan::tree::<impl Transaction<T, R, W>>::extend`
   --> /home/chris/.cargo/registry/src/github.com-1ecc6299db9ec823/banyan-0.17.1/src/tree.rs:562:12
    |
562 |         V: BanyanValue,
    |            ^^^^^^^^^^^ required by this bound in `banyan::tree::<impl Transaction<T, R, W>>::extend`

The notion that those traits are not implemented is confounding because they are pretty explicitly implemented:

impl libipld_core::codec::Encode<libipld_cbor::DagCborCodec> for SimpleRow {
    fn encode<W: std::io::Write>(
        &self,
        c: libipld_cbor::DagCborCodec,
        w: &mut W,
    ) -> libipld_core::error::Result<()> {
        todo!();
    }
}

impl libipld_core::codec::Decode<libipld_cbor::DagCborCodec> for SimpleRow {
    fn decode<R: std::io::Read + std::io::Seek>(
        c: libipld_cbor::DagCborCodec,
        r: &mut R,
    ) -> libipld_core::error::Result<Self> {
        todo!();
    }
}

Clearly the actual implementation needs to be written, but this should compile, I would think. My general practice is to write a stub with todo!(), write tests, then write the implementation.

Ok, figured it out. The version of Banyan in crates.io depends on libipld 0.12 and I was using the latest 0.16.

I learned that:

  1. Rust will let you have two versions of the same library in one project.
  2. All the symbols from the two versions refer to different things.

I was implementing Encode and Decode for libipld 0.16 but Banyan needed them implemented for libipld 0.12.