github.com/ipld/go-ipld-prime@v0.21.0/linking/linkingExamples_test.go (about) 1 package linking_test 2 3 import ( 4 "fmt" 5 6 "github.com/ipfs/go-cid" 7 8 _ "github.com/ipld/go-ipld-prime/codec/dagcbor" 9 "github.com/ipld/go-ipld-prime/fluent" 10 "github.com/ipld/go-ipld-prime/linking" 11 cidlink "github.com/ipld/go-ipld-prime/linking/cid" 12 "github.com/ipld/go-ipld-prime/node/basicnode" 13 "github.com/ipld/go-ipld-prime/storage/memstore" 14 ) 15 16 // storage is a map where we'll store serialized IPLD data. 17 // 18 // ExampleLinkSystem_Store will put data into this; 19 // ExampleLinkSystem_Load will read out from it. 20 // 21 // In a real program, you'll probably make functions to load and store from disk, 22 // or some network storage, or... whatever you want, really :) 23 var store = memstore.Store{} 24 25 // TODO: These examples are really heavy on CIDs and the multicodec and multihash magic tables. 26 // It would be good to have examples that create and use less magical LinkSystem constructions, too. 27 28 func ExampleLinkSystem_Store() { 29 // Creating a Link is done by choosing a concrete link implementation (typically, CID), 30 // getting a LinkSystem that knows how to work with that, and then using the LinkSystem methods. 31 32 // Let's get a LinkSystem. We're going to be working with CID links, 33 // so let's get the default LinkSystem that's ready to work with those. 34 lsys := cidlink.DefaultLinkSystem() 35 36 // We want to store the serialized data somewhere. 37 // We'll use an in-memory store for this. (It's a package scoped variable.) 38 // You can use any kind of storage system here; 39 // or if you need even more control, you could also write a function that conforms to the linking.BlockWriteOpener interface. 40 lsys.SetWriteStorage(&store) 41 42 // To create any links, first we need a LinkPrototype. 43 // This gathers together any parameters that might be needed when making a link. 44 // (For CIDs, the version, the codec, and the multihash type are all parameters we'll need.) 45 // Often, you can probably make this a constant for your whole application. 46 lp := cidlink.LinkPrototype{Prefix: cid.Prefix{ 47 Version: 1, // Usually '1'. 48 Codec: 0x71, // 0x71 means "dag-cbor" -- See the multicodecs table: https://github.com/multiformats/multicodec/ 49 MhType: 0x13, // 0x20 means "sha2-512" -- See the multicodecs table: https://github.com/multiformats/multicodec/ 50 MhLength: 64, // sha2-512 hash has a 64-byte sum. 51 }} 52 53 // And we need some data to link to! Here's a quick piece of example data: 54 n := fluent.MustBuildMap(basicnode.Prototype.Map, 1, func(na fluent.MapAssembler) { 55 na.AssembleEntry("hello").AssignString("world") 56 }) 57 58 // Before we use the LinkService, NOTE: 59 // There's a side-effecting import at the top of the file. It's for the dag-cbor codec. 60 // The CID LinkSystem defaults use a global registry called the multicodec table; 61 // and the multicodec table is populated in part by the dag-cbor package when it's first imported. 62 // You'll need that side-effecting import, too, to copy this example. 63 // It can happen anywhere in your program; once, in any package, is enough. 64 // If you don't have this import, the codec will not be registered in the multicodec registry, 65 // and when you use the LinkSystem we got from the cidlink package, it will return an error of type ErrLinkingSetup. 66 // If you initialize a custom LinkSystem, you can control this more directly; 67 // these registry systems are only here as defaults. 68 69 // Now: time to apply the LinkSystem, and do the actual store operation! 70 lnk, err := lsys.Store( 71 linking.LinkContext{}, // The zero value is fine. Configure it it you want cancellability or other features. 72 lp, // The LinkPrototype says what codec and hashing to use. 73 n, // And here's our data. 74 ) 75 if err != nil { 76 panic(err) 77 } 78 79 // That's it! We got a link. 80 fmt.Printf("link: %s\n", lnk) 81 fmt.Printf("concrete type: `%T`\n", lnk) 82 83 // Remember: the serialized data was also stored to the 'store' variable as a side-effect. 84 // (We set this up back when we customized the LinkSystem.) 85 // We'll pick this data back up again in the example for loading. 86 87 // Output: 88 // link: bafyrgqhai26anf3i7pips7q22coa4sz2fr4gk4q4sqdtymvvjyginfzaqewveaeqdh524nsktaq43j65v22xxrybrtertmcfxufdam3da3hbk 89 // concrete type: `cidlink.Link` 90 } 91 92 func ExampleLinkSystem_Load() { 93 // Let's say we want to load this link (it's the same one we created in ExampleLinkSystem_Store). 94 cid, _ := cid.Decode("bafyrgqhai26anf3i7pips7q22coa4sz2fr4gk4q4sqdtymvvjyginfzaqewveaeqdh524nsktaq43j65v22xxrybrtertmcfxufdam3da3hbk") 95 lnk := cidlink.Link{Cid: cid} 96 97 // Let's get a LinkSystem. We're going to be working with CID links, 98 // so let's get the default LinkSystem that's ready to work with those. 99 // (This is the same as we did in ExampleLinkSystem_Store.) 100 lsys := cidlink.DefaultLinkSystem() 101 102 // We need somewhere to go looking for any of the data we might want to load! 103 // We'll use an in-memory store for this. (It's a package scoped variable.) 104 // (This particular memory store was filled with the data we'll load earlier, during ExampleLinkSystem_Store.) 105 // You can use any kind of storage system here; 106 // or if you need even more control, you could also write a function that conforms to the linking.BlockReadOpener interface. 107 lsys.SetReadStorage(&store) 108 109 // We'll need to decide what in-memory implementation of datamodel.Node we want to use. 110 // Here, we'll use the "basicnode" implementation. This is a good getting-started choice. 111 // But you could also use other implementations, or even a code-generated type with special features! 112 np := basicnode.Prototype.Any 113 114 // Before we use the LinkService, NOTE: 115 // There's a side-effecting import at the top of the file. It's for the dag-cbor codec. 116 // See the comments in ExampleLinkSystem_Store for more discussion of this and why it's important. 117 118 // Apply the LinkSystem, and ask it to load our link! 119 n, err := lsys.Load( 120 linking.LinkContext{}, // The zero value is fine. Configure it it you want cancellability or other features. 121 lnk, // The Link we want to load! 122 np, // The NodePrototype says what kind of Node we want as a result. 123 ) 124 if err != nil { 125 panic(err) 126 } 127 128 // Tada! We have the data as node that we can traverse and use as desired. 129 fmt.Printf("we loaded a %s with %d entries\n", n.Kind(), n.Length()) 130 131 // Output: 132 // we loaded a map with 1 entries 133 }