This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

Save before starting on Wasm

+321 -247
+4
Cargo.toml
··· 29 29 # See https://blog.rust-lang.org/2021/03/25/Rust-1.51.0.html#splitting-debug-information 30 30 [profile.dev] 31 31 split-debuginfo = "unpacked" 32 + 33 + [profile.release] 34 + lto = true 35 + opt-level = 'z'
+6 -6
flake.lock
··· 55 55 }, 56 56 "nixpkgs_2": { 57 57 "locked": { 58 - "lastModified": 1702759837, 59 - "narHash": "sha256-u3XeJVRe/Q975nwFE+6ALEwypMKJEELMJKDAhSKyq3M=", 58 + "lastModified": 1703351344, 59 + "narHash": "sha256-9FEelzftkE9UaJ5nqxidaJJPEhe9TPhbypLHmc2Mysc=", 60 60 "owner": "NixOS", 61 61 "repo": "nixpkgs", 62 - "rev": "b2566f4f897ac6224e094b167d9488d03e157f28", 62 + "rev": "7790e078f8979a9fcd543f9a47427eeaba38f268", 63 63 "type": "github" 64 64 }, 65 65 "original": { ··· 86 86 ] 87 87 }, 88 88 "locked": { 89 - "lastModified": 1702952173, 90 - "narHash": "sha256-24kUnTZgXP5B/fs1/f61tJuHyFrJ8824rn1B/0hL1og=", 89 + "lastModified": 1703470538, 90 + "narHash": "sha256-NVFMSr99F0TIqVWBwDqMH6lWoM4PVyzMtI+CPGRIscg=", 91 91 "owner": "oxalica", 92 92 "repo": "rust-overlay", 93 - "rev": "20fd62b0891707a1db8117d09fc3e65a1cd0f6d7", 93 + "rev": "f2b937756343365f9b1ba66ec7a1ca489aef745c", 94 94 "type": "github" 95 95 }, 96 96 "original": {
+2
flake.nix
··· 62 62 63 63 cargo-installs = [ 64 64 pkgs.cargo-bootimage 65 + pkgs.cargo-component 65 66 pkgs.cargo-criterion 66 67 pkgs.cargo-deny 67 68 pkgs.cargo-expand ··· 83 84 rust-toolchain 84 85 85 86 pkgs.wasmtime 87 + pkgs.binaryen 86 88 pkgs.sccache 87 89 self.packages.${system}.irust 88 90 ]
+1 -3
src/inliner.rs
··· 1 - //! Strategies for inlining [`Ipld`][libipld::ipld::Ipld] 2 - //! 3 - //! The primary interface for inlining is [`Inliner::run`] 1 + //! Inlining [`Ipld`][libipld::ipld::Ipld] from a content addressed store 4 2 pub mod at_most_once; 5 3 pub mod exactly_once; 6 4 pub mod naive;
+28 -20
src/inliner/at_most_once.rs
··· 1 1 //! Inlining each subgraph at most once (deduplicated) 2 - use super::{exactly_once::ExactlyOnce, naive::Naive}; 2 + use super::{exactly_once::ExactlyOnce, naive::Naive, traits::*}; 3 3 use crate::store::traits::Store; 4 4 use libipld::{cid::Cid, ipld::Ipld}; 5 5 use std::collections::HashSet; ··· 58 58 } 59 59 } 60 60 61 - // impl<'a, S: Store + ?Sized> Iterator for AtMostOnce<'a, S> { 62 - // type Item = Result<Ipld, Cid>; 63 - // 64 - // fn next(&mut self) -> Option<Self::Item> { 65 - // if let Ok(stuck) = self.exactly_once.try_into() { 66 - // if !self.seen.contains(&stuck.needs) { 67 - // return None; 68 - // } 69 - // } 70 - // 71 - // match self.exactly_once.next()?.try_into() { 72 - // Ok(Some(Ok(stuck))) => { 73 - // stuck.ignore(); 74 - // Some(Err(stuck.needs)) 75 - // } 76 - // otherwise => otherwise, 77 - // } 78 - // } 79 - // } 61 + impl<'a, S: Store + ?Sized> Iterator for AtMostOnce<'a, S> { 62 + type Item = Result<Ipld, Cid>; 63 + 64 + fn next(&mut self) -> Option<Self::Item> { 65 + match self.exactly_once.next()? { 66 + Err(needs) => { 67 + if self.seen.contains(&needs) { 68 + self.exactly_once.interject(&Ipld::Link(needs)); 69 + Some(Ok(Ipld::Link(needs))) 70 + } else { 71 + None 72 + } 73 + } 74 + good => Some(good), 75 + } 76 + } 77 + } 78 + 79 + impl<'a, S: Store + ?Sized> Inliner<'a> for AtMostOnce<'a, S> { 80 + fn store(&mut self, cid: &Cid, ipld: &Ipld) { 81 + self.exactly_once.store(cid, ipld); 82 + } 83 + 84 + fn interject(&mut self, ipld: &Ipld) { 85 + self.exactly_once.interject(ipld) 86 + } 87 + }
+42 -63
src/inliner/exactly_once.rs
··· 1 - //! An inliner that stops if it is unable to find a subgraph 1 + // FIXME this does NOT have exactly once semantics 2 2 3 - use super::{ 4 - naive::Naive, 5 - traits::{Inliner, Stuck}, 6 - }; 3 + //! An inliner that stops if it is unable to find a subgraph 4 + use super::{naive::Naive, traits::Inliner}; 7 5 use crate::store::traits::Store; 8 - use libipld::{cid::Cid, ipld, ipld::Ipld}; 9 - 10 - ///////////////// 11 - // ExactlyOnce // 12 - ///////////////// 6 + use libipld::{cid::Cid, ipld::Ipld}; 13 7 14 8 /// [`Ipld`] inliner that only inlines a [`Cid`] once 15 9 /// 16 10 /// Unlike [`AtMostOnce`][crate::inliner::at_most_once::AtMostOnce], this inliner will stops if the [`Cid`] is not availale from the [`Store`]. 17 - #[derive(PartialEq, Debug)] 11 + #[derive(Debug, PartialEq)] 18 12 pub struct ExactlyOnce<'a, S: Store + ?Sized> { 19 13 naive: Naive<'a, S>, 20 14 needs: Option<Cid>, 15 + } 16 + 17 + impl<'a, S: Store + ?Sized> ExactlyOnce<'a, S> { 18 + /// Initialize a new [`ExactlyOnce`] 19 + pub fn new(ipld: Ipld, store: &'a mut S) -> Self { 20 + ExactlyOnce { 21 + naive: Naive::new(ipld, store), 22 + needs: None, 23 + } 24 + } 21 25 } 22 26 23 27 impl<'a, S: Store + ?Sized> From<Naive<'a, S>> for ExactlyOnce<'a, S> { ··· 51 55 } 52 56 } 53 57 54 - // FIXME with_stuck or similar? 55 - impl<'a, S: Store + ?Sized> ExactlyOnce<'a, S> { 56 - /// Initialize a new [`ExactlyOnce`] 57 - pub fn new(ipld: Ipld, store: &'a mut S) -> Self { 58 - ExactlyOnce { 59 - naive: Naive::new(ipld, store), 60 - needs: None, 61 - } 58 + impl<'a, S: Store + ?Sized> Inliner<'a> for ExactlyOnce<'a, S> { 59 + fn store(&mut self, cid: &Cid, ipld: &Ipld) { 60 + self.naive.store.put_keyed(cid.clone(), ipld.clone()) // FIXME attack of the clone 61 + } 62 + 63 + fn interject(&mut self, ipld: &Ipld) { 64 + self.needs = None; 65 + self.naive.push(ipld.clone()) // FIXME attack of the clones 62 66 } 63 67 } 64 68 65 69 // FIXME 66 - // impl<'a, S: Store + ?Sized> Inliner<'a> for ExactlyOnce<'a, S> { 67 - // fn run(&'a mut self) -> Result<Ipld, Stuck<'a, Self>> { 68 - // match self.last() { 69 - // Some(result) => result, 70 - // None => Stuck { 71 - // // Impossible?! I dunno, feels bad :/ Maybe wrap iterator in an Internal? 72 - // }, 73 - // } 74 - // } 75 - // 76 - // // OLD VERSION 77 - // pub fn run(&'a mut self) -> Option<Result<Ipld, Stuck<'a, S>>> { 78 - // match self.last() { 79 - // Some(Ok(ipld)) => Some(Ok(ipld)), 80 - // Some(Err(cid)) => Some(Err(Stuck { 81 - // needs: cid, 82 - // iterator: self, 83 - // })), 84 - // None => None, 85 - // } 86 - // } 87 - // } 88 - // } 70 + #[cfg(test)] 71 + mod tests { 72 + use super::*; 73 + use crate::store::memory::MemoryStore; 74 + use libipld::ipld; 75 + use pretty_assertions::assert_eq; 76 + 77 + // FIXME 78 + #[test] 79 + fn happy_little_test() { 80 + let mut store = MemoryStore::new(); 81 + let mut c = ExactlyOnce::new(ipld!([1, 2, 3]), &mut store); 82 + match c.tryme() { 83 + Ok(_) => assert!(true), 84 + Err(_) => assert!(true), 85 + } 89 86 90 - // FIXME 91 - // #[cfg(test)] 92 - // mod tests { 93 - // use super::*; 94 - // use crate::store::memory::MemoryStore; 95 - // use libipld::ipld; 96 - // use pretty_assertions::assert_eq; 97 - // 98 - // // FIXME 99 - // #[test] 100 - // fn happy_little_test() { 101 - // let mut store = MemoryStore::new(); 102 - // let mut c = ExactlyOnce::new(ipld!([1, 2, 3]), &mut store); 103 - // match c.tryme() { 104 - // Ok(_) => assert!(true), 105 - // Err(_) => assert!(true), 106 - // } 107 - // 108 - // assert!(true); 109 - // } 110 - // } 87 + assert!(true); 88 + } 89 + }
+1 -1
src/inliner/naive.rs
··· 12 12 /// Inline directly, without deduplication or stopping at missing nodes 13 13 /// 14 14 /// More sophisticated inlining strategies are available in the [`Inliner`][ipld_inline::inliner] module 15 - #[derive(PartialEq, Debug)] 15 + #[derive(Debug, PartialEq)] 16 16 pub struct Naive<'a, S: Store + ?Sized> { 17 17 po: PostOrderIpldIter, 18 18 stack: Vec<Ipld>,
+113 -41
src/inliner/traits.rs
··· 1 - use crate::{inline_ipld, store::traits::Store}; 2 - use libipld::{ipld, Cid, Ipld}; 1 + //! Traits for inlining [`Ipld`] 2 + use crate::ipld::inline_ipld; 3 + use libipld::{Cid, Ipld}; 3 4 4 - pub trait Inliner<'a> { 5 - // FIXME 6 - // /// The primary interface for [`Inliner`]s 7 - // /// 8 - // /// # Examples 9 - // /// 10 - // /// ``` 11 - // /// # use ipld_inline::{ 12 - // /// # inliner::exactly_once::ExactlyOnce, 13 - // /// # store::{ 14 - // /// # traits::Store, 15 - // /// # memory::MemoryStore 16 - // /// # } 17 - // /// # }; 18 - // /// # use libipld::{ipld, cid::{CidGeneric, Version}}; 19 - // /// # use libipld_cbor::DagCborCodec; 20 - // /// # use multihash::Code::Sha2_256; 21 - // /// # 22 - // /// let mut store = MemoryStore::new(); 23 - // /// let cid = store.put(ipld!([1, 2, 3]), DagCborCodec, &Sha2_256, Version::V1).unwrap(); 24 - // /// 25 - // /// let mut exactly_once = ExactlyOnce::new(ipld!({"a": 1, "b": cid}), &mut store); 26 - // /// let expected = ipld!({"a": 1, "b": {"/": {"link": cid, "data": [1, 2, 3]}}}); 27 - // /// 28 - // /// assert_eq!(exactly_once.run().unwrap().unwrap(), expected); 29 - // /// ``` 30 - // /// FIXME the above can't compare in the eq 31 - // /// FIXME show the err case 32 - fn run(&'a mut self) -> Result<&Ipld, Stuck<'a, Self>>; 5 + /// A trait for inlining [`Ipld`] 6 + pub trait Inliner<'a>: Iterator<Item = Result<Ipld, Cid>> { 7 + // These are shared with Stuck... should that get extracted? 33 8 34 - // These are shared with Stuck... should that get extracted? 9 + /// Store some [`Ipld`] in the [`Inliner`]'s state 10 + /// 11 + /// This is useful for deduplication, avoiding [`Stuck`] states, and so on 12 + /// 13 + /// # Arguments 14 + /// 15 + /// * `self` - The [`Inliner`] 16 + /// * `cid` - The [`Cid`] to use as a key. It's relationship to `ipld` is not checked. 17 + /// * `ipld` - The [`Ipld`] to store 18 + /// 19 + /// # Examples 20 + /// 21 + /// FIXME 22 + /// # use pretty_assertions::assert_eq; 35 23 fn store(&mut self, cid: &Cid, ipld: &Ipld); 36 - fn stub(&mut self, ipld: &Ipld) -> (); 37 - fn skip(&'a mut self) -> &'a mut Self; // FIXME 24 + 25 + /// Push some [`Ipld`] into the processing queue state of the [`Inliner`] 26 + /// 27 + /// Roughly "skipping the line" with some new `Ipld` to directly edit the output during DAG construction. 28 + /// This is especially helpful for resolving missing [`Ipld`] segments without permanently storing it. 29 + /// 30 + /// # Arguments 31 + /// 32 + /// * `self` - The [`Inliner`] 33 + /// * `ipld` - The [`Ipld`] to push into procesisng queue 34 + /// 35 + /// # Examples 36 + /// 37 + /// FIXME 38 + /// # use pretty_assertions::assert_eq; 39 + fn interject(&mut self, ipld: &Ipld); // NOTE TO SELF: in definition, set `needs = None` 40 + 41 + /// Run the [`Inliner`] until completion or unable to progress 42 + /// 43 + /// # Examples 44 + /// 45 + /// ``` 46 + /// # use ipld_inline::{ 47 + /// # inliner::exactly_once::ExactlyOnce, 48 + /// # store::{ 49 + /// # traits::Store, 50 + /// # memory::MemoryStore 51 + /// # } 52 + /// # }; 53 + /// # use libipld::{ipld, cid::{CidGeneric, Version}}; 54 + /// # use libipld_cbor::DagCborCodec; 55 + /// # use multihash::Code::Sha2_256; 56 + /// # use pretty_assertions::assert_eq; 57 + /// # 58 + /// let mut store = MemoryStore::new(); 59 + /// let cid = store.put(ipld!([1, 2, 3]), DagCborCodec, &Sha2_256, Version::V1).unwrap(); 60 + /// 61 + /// let mut exactly_once = ExactlyOnce::new(ipld!({"a": 1, "b": cid}), &mut store); 62 + /// let expected = ipld!({"a": 1, "b": {"/": {"link": cid, "data": [1, 2, 3]}}}); 63 + /// 64 + /// assert_eq!(exactly_once.run().unwrap().unwrap(), expected); 65 + /// ``` 66 + /// 67 + /// FIXME show the err case 68 + fn run(&'a mut self) -> Option<Result<Ipld, Stuck<'a, Self>>> { 69 + let result = self.last()?; 70 + let lifted = result.map_err(|needs| self.stuck_at(needs)); 71 + Some(lifted) 72 + } 73 + 74 + /// Manually convert an [`Inliner`] to a [`Stuck`] 75 + /// 76 + /// # Arguments 77 + /// 78 + /// * `self` - The [`Inliner`] 79 + /// * `needs` - The [`Cid`] that's required in order to continue 80 + /// 81 + /// # Examples 82 + /// 83 + /// ``` 84 + /// # use ipld_inline::{ 85 + /// # inliner::{ 86 + /// # exactly_once::ExactlyOnce, 87 + /// # traits::{Inliner, Stuck} 88 + /// # }, 89 + /// # store::{ 90 + /// # traits::Store, 91 + /// # memory::MemoryStore 92 + /// # } 93 + /// # }; 94 + /// # use libipld::{ipld, Ipld, cid::{CidGeneric, Version}}; 95 + /// # use libipld_cbor::DagCborCodec; 96 + /// # use multihash::Code::Sha2_256; 97 + /// # use std::str::FromStr; 98 + /// # use pretty_assertions::assert_eq; 99 + /// # 100 + /// let mut store = MemoryStore::new(); 101 + /// let cid = FromStr::from_str("bafyreickxqyrg7hhhdm2z24kduovd4k4vvbmfmenzn7nc6pxg6qzjm2v44").unwrap(); 102 + /// 103 + /// let mut inliner = ExactlyOnce::new(Ipld::Null, &mut store); 104 + /// assert_eq!(inliner.stuck_at(cid).needs, cid); 105 + /// ``` 106 + fn stuck_at(&'a mut self, needs: Cid) -> Stuck<'a, Self> { 107 + Stuck { 108 + needs, 109 + inliner: self, 110 + } 111 + } 38 112 } 39 113 40 114 /// Error state if a [`Cid`] is not available from the [`ExactlyOnce`]'s [`Store`] ··· 114 188 /// assert_eq!(observed, Some(expected)); 115 189 /// ``` 116 190 pub fn stub(&'a mut self, ipld: &Ipld) -> &'a mut I { 117 - let dag = ipld.clone(); 118 - let link = self.needs.clone(); 119 - let inlined = inline_ipld!(link, dag); 191 + self.inliner 192 + .interject(&inline_ipld(self.needs.clone(), ipld.clone())); 120 193 121 - self.inliner.stub(&inlined); 122 - self.inliner.skip() // TODO needs = None; 194 + self.inliner 123 195 } 124 196 125 197 /// Ignore the stuck [`Cid`] to return to normal [`ExactlyOnce`] operation ··· 152 224 /// assert_eq!(observed, Some(expected)); 153 225 /// ``` 154 226 pub fn ignore(&'a mut self) -> &'a mut I { 155 - self.inliner.stub(&Ipld::Link(self.needs.clone())); 156 - self.inliner.skip() 227 + self.inliner.interject(&Ipld::Link(self.needs.clone())); 228 + self.inliner 157 229 } 158 230 }
+122 -107
src/ipld.rs
··· 1 1 //! Helpers for building properly delimited and linked inline IPLD 2 - use libipld::{ipld, Ipld}; 3 - 4 - pub const DELIMIT_INLINE: &'static str = "/"; 5 - pub const DATA_TAG: &'static str = "data"; 6 - pub const LINK_TAG: &'static str = "link"; 2 + //! 3 + //! # Examples 4 + //! 5 + //! ``` 6 + //! # use ipld_inline::{cid, ipld::*}; 7 + //! # use multihash::Code::Sha2_256; 8 + //! # use libipld::{ 9 + //! # cid::Version, 10 + //! # cbor::DagCborCodec, 11 + //! # ipld, 12 + //! # Ipld 13 + //! # }; 14 + //! # 15 + //! let given_cid = cid::new(&ipld!([1,2,3]), DagCborCodec, &Sha2_256, Version::V1).unwrap(); 16 + //! let calculated_cid = cid::new(&ipld!([4, 5, 6]), DagCborCodec, &Sha2_256, Version::V1).unwrap(); 17 + //! 18 + //! let observed = ipld!({ 19 + //! "a": "foo", 20 + //! "b": inline_ipld_inherit(ipld!({ 21 + //! "c": "bar", 22 + //! "d": inline_ipld(given_cid, ipld!([1, 2, 3])) 23 + //! })), 24 + //! "e": inline_ipld_link(DagCborCodec, &Sha2_256, ipld!([4, 5, 6])) 25 + //! }); 26 + //! 27 + //! assert_eq!(observed, ipld!( 28 + //! { 29 + //! "a": "foo", 30 + //! "b": { 31 + //! "/": { 32 + //! // "link": omited 33 + //! "data": { 34 + //! "c": "bar", 35 + //! "d": {"/": {"link": given_cid, "data": [1, 2, 3]}} 36 + //! } 37 + //! } 38 + //! }, 39 + //! "e": {"/": {"link": calculated_cid, "data": [4, 5, 6]} 40 + //! } 41 + //! }) 42 + //! ); 43 + //! ``` 44 + use crate::cid; 45 + use libipld::{ 46 + cid::Version, 47 + codec::{Codec, Encode}, 48 + ipld, Cid, Ipld, 49 + }; 50 + use multihash::MultihashDigest; 7 51 8 - /// A helper for creating properly delimited inline IPLD 52 + /// Wrap some [`Ipld`] and manually associated [`Cid`] in an inline delimiter 53 + /// 54 + /// To have the [`Cid`] calculated at runtime, use [`inline_ipld_link`]. 55 + /// [`inline_ipld`] *does not* check that the [`Cid`] actually corresponds to the associated [`Ipld`]. 9 56 /// 10 - /// `inline_ipld!` automatically wraps the enclosed [`Ipld`] in the correct delimiters. 11 - /// It has three arities: 57 + /// # Arguments 12 58 /// 13 - /// ## Unary 59 + /// * `cid` - The [`Cid`] for the `"link"` field 60 + /// * `ipld` - The [`Ipld`] to inline 14 61 /// 15 - /// ```no_run 16 - /// # use ipld_inline::{cid, inline_ipld}; 17 - /// # use libipld::{ipld, Ipld}; 62 + /// ``` 63 + /// # use ipld_inline::{cid, ipld::inline_ipld}; 64 + /// # use libipld::{ipld, Ipld, Cid}; 65 + /// # use std::str::FromStr; 18 66 /// # 19 - /// # let ipld = Ipld::Null; 20 - /// # 21 - /// inline_ipld!(ipld); 67 + /// let cid: Cid = FromStr::from_str("bafyreihscx57i276zr5pgnioa5omevods6eseu5h4mllmow6csasju6eqi").unwrap(); 68 + /// assert_eq!(inline_ipld(cid, ipld!([1, 2, 3])), ipld!({ 69 + /// "/": { 70 + /// "data": ipld!([1, 2, 3]), 71 + /// "link": cid 72 + /// } 73 + /// })); 22 74 /// ``` 75 + pub fn inline_ipld(cid: Cid, ipld: Ipld) -> Ipld { 76 + ipld!({ 77 + "/": { 78 + "data": ipld!(ipld), 79 + "link": Ipld::Link(cid) 80 + } 81 + }) 82 + } 83 + 84 + /// Create inline-delimited [`Ipld`], but omit the `"link"` field 23 85 /// 24 - /// The unary variant omits the `"link"` field. Per the [spec], this causes the extracted 86 + /// `inline_ipld_inherit` wraps the enclosed [`Ipld`] in the correct delimiters. 87 + /// It omits the `"link"` field. Per the [spec], this causes the extracted 25 88 /// IPLD link to inherit the coedec and CID encoding of its parent. 26 89 /// 27 90 /// [spec]: https://github.com/ucan-wg/ipld-inline-links 28 91 /// 29 - /// ## Binary 92 + /// # Arguments 30 93 /// 31 - /// ```no_run 32 - /// # use ipld_inline::{cid, inline_ipld}; 33 - /// # use libipld::{ipld, Ipld, Cid}; 34 - /// # use std::str::FromStr; 35 - /// # 36 - /// # let ipld = ipld!(""); 37 - /// # let cid: Cid = FromStr::from_str("bafyreihscx57i276zr5pgnioa5omevods6eseu5h4mllmow6csasju6eqi").unwrap(); 94 + /// * `ipld` - The [`Ipld`] to wrap in the inlined delimiter 95 + /// 96 + /// # Examples 97 + /// 98 + /// ``` 99 + /// # use ipld_inline::{cid, ipld::inline_ipld_inherit}; 100 + /// # use libipld::{ipld, Ipld}; 38 101 /// # 39 - /// inline_ipld!(cid, ipld); 102 + /// let observed = inline_ipld_inherit(ipld!([1, 2, 3])); 103 + /// assert_eq!(observed, ipld!({"/": {"data": ipld!([1, 2, 3])}})); 40 104 /// ``` 105 + pub fn inline_ipld_inherit(ipld: Ipld) -> Ipld { 106 + ipld!({"/": {"data": ipld!(ipld)}}) 107 + } 108 + 109 + /// Create inline-delimited [`Ipld`], and automatically calculate the [`Cid`] 41 110 /// 42 - /// The binary variant accepts an explicit [`Cid`][libipld::cid::Cid] parameter. 43 - /// This *does not* check that the [`Cid`][libipld::cid::Cid] actually corresponds to the associated [`Ipld`]. 111 + /// Unlike [`inline_ipld`], [`inline_ipld_link`] calculates a correct `"link"` based on 112 + /// the codec and digest function passed in. It always uses to CIDv1. 44 113 /// 45 - /// ## Ternary 114 + /// # Arguments 46 115 /// 47 - /// ```no_run 48 - /// # use ipld_inline::{cid, inline_ipld}; 49 - /// # use multihash::Code::Sha2_256; 50 - /// # use libipld::{ 51 - /// # cid::Version, 52 - /// # cbor::DagCborCodec, 53 - /// # ipld, 54 - /// # Ipld 55 - /// # }; 56 - /// # 57 - /// # let digester = DagCborCodec; 58 - /// # let codec = Sha2_256; 59 - /// # let ipld = Ipld::Null; 60 - /// # 61 - /// inline_ipld!(digester, codec, ipld); 62 - /// ``` 63 - /// 64 - /// The ternary variant calculates the correct `"link"` (at runtime) based on the configuration passed in. 116 + /// * `codec` - The codec to encode the [`Ipld`] with when generating the [`Cid`] 117 + /// * `digester` - The hash function for the [`Cid`] 118 + /// * `ipld` - The [`Ipld`] to inline 65 119 /// 66 120 /// # Examples 67 121 /// 68 - /// The following example includes all arities of `inline_ipld!`. 69 - /// 70 - /// ```no_run 71 - /// # use ipld_inline::{cid, inline_ipld}; 122 + /// ``` 123 + /// # use ipld_inline::{cid, ipld::inline_ipld_link}; 124 + /// # use std::str::FromStr; 72 125 /// # use multihash::Code::Sha2_256; 73 126 /// # use libipld::{ 74 127 /// # cid::Version, 75 128 /// # cbor::DagCborCodec, 76 129 /// # ipld, 77 - /// # Ipld 130 + /// # Ipld, 131 + /// # Cid 78 132 /// # }; 79 133 /// # 80 - /// let given_cid = cid::new(&ipld!([1,2,3]), DagCborCodec, &Sha2_256, Version::V1).unwrap(); 81 - /// let calculated_cid = cid::new(&ipld!([4, 5, 6]), DagCborCodec, &Sha2_256, Version::V1).unwrap(); 82 - /// 83 - /// let observed = ipld!({ 84 - /// "a": "foo", 85 - /// "b": inline_ipld!({ // Unary 86 - /// "c": "bar", 87 - /// "d": inline_ipld!(given_cid, [1, 2, 3]) // Binary 88 - /// }), 89 - /// "e": inline_ipld!(DagCborCodec, Sha2_256, [4, 5, 6]) // Ternary 90 - /// }); 91 - /// 92 - /// assert_eq!(observed, ipld!( 93 - /// { 94 - /// "a": "foo", 95 - /// "b": { 96 - /// "/": { 97 - /// // Unary omits the `"link"` field 98 - /// // "link": not here, 99 - /// "data": { 100 - /// "c": "bar", 101 - /// // Binary includes the given `"link"` 102 - /// // vvvvvvvvv 103 - /// "d": {"/": {"link": given_cid, "data": [1, 2, 3]}} 104 - /// } 105 - /// } 106 - /// }, 107 - /// // Ternary uses the calculated `"link"` 108 - /// // vvvvvvvvvvvvvv 109 - /// "e": {"/": {"link": calculated_cid, "data": [4, 5, 6]} 110 - /// } 111 - /// }) 112 - /// ); 134 + /// let cid: Cid = FromStr::from_str("bafyreickxqyrg7hhhdm2z24kduovd4k4vvbmfmenzn7nc6pxg6qzjm2v44").unwrap(); 135 + /// let observed = inline_ipld_link(DagCborCodec, &Sha2_256, ipld!([1, 2, 3])); 136 + /// assert_eq!(observed, ipld!({"/": {"data": ipld!([1,2, 3]), "link": cid}})); 113 137 /// ``` 114 - #[macro_export] 115 - macro_rules! inline_ipld { 116 - ($ipld: tt) => { 117 - ipld!({"/": {"data": ipld!($ipld)}}) 118 - }; 119 - 120 - ($cid: tt, $ipld: tt) => { 121 - ipld!({ 122 - "/": { 123 - "data": ipld!($ipld), 124 - "link": Ipld::Link($cid) 125 - } 126 - }) 127 - }; 128 - 129 - ($digester: tt, $codec: tt, $ipld: tt) => { 130 - ipld!({ 131 - "/": { 132 - "data": ipld!($ipld), 133 - "link": Ipld::Link(cid::new(&ipld!($ipld), $digester, &$codec, Version::V1).unwrap()) 134 - } 135 - }) 136 - }; 138 + pub fn inline_ipld_link<C: Codec, D: MultihashDigest<64>>( 139 + codec: C, 140 + digester: &D, 141 + ipld: Ipld, 142 + ) -> Ipld 143 + where 144 + Ipld: Encode<C>, 145 + { 146 + ipld!({ 147 + "/": { 148 + "data": ipld.clone(), 149 + "link": Ipld::Link(cid::new(&ipld, codec, digester, Version::V1).unwrap()) 150 + } 151 + }) 137 152 }
+1 -1
src/store/memory.rs
··· 5 5 use std::collections::BTreeMap; 6 6 7 7 /// A basic in-memory [`Ipld`] store 8 - #[derive(Clone, Debug, Default)] 8 + #[derive(Clone, Debug, Default, PartialEq)] 9 9 pub struct MemoryStore { 10 10 store: BTreeMap<Cid, Ipld>, 11 11 }
+1 -5
src/store/traits.rs
··· 1 1 //! Content-addressed store trait 2 - use crate::cid; 3 - use crate::extractor::Extractor; 4 - use crate::inliner::at_most_once::AtMostOnce; 5 - use crate::inliner::exactly_once::ExactlyOnce; 6 - use crate::inliner::naive::Naive; 2 + use crate::{cid, extractor::Extractor, inliner::exactly_once::ExactlyOnce}; 7 3 use libipld::{ 8 4 cid::{Cid, Version}, 9 5 codec::{Codec, Encode},