This repository has been archived by the owner on Aug 9, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #7 from mildred/mildred-ipld
Implement stripping LD directives from IPLD Node, and transforming IPLD to JSON-LD
- Loading branch information
Showing
6 changed files
with
367 additions
and
47 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
package jsonld | ||
|
||
import ( | ||
"testing" | ||
"reflect" | ||
|
||
ipld "github.com/ipfs/go-ipld" | ||
) | ||
|
||
type TC struct { | ||
src ipld.Node | ||
jsonld ipld.Node | ||
} | ||
|
||
var testCases []TC | ||
|
||
func init() { | ||
testCases = append(testCases, TC{ | ||
src: ipld.Node{ | ||
"foo": "bar", | ||
"bar": []int{1, 2, 3}, | ||
"baz": ipld.Node{ | ||
"mlink": "QmZku7P7KeeHAnwMr6c4HveYfMzmtVinNXzibkiNbfDbPo", | ||
}, | ||
}, | ||
jsonld: ipld.Node{ | ||
"foo": "bar", | ||
"bar": []int{1, 2, 3}, | ||
"baz": ipld.Node{ | ||
"mlink": "QmZku7P7KeeHAnwMr6c4HveYfMzmtVinNXzibkiNbfDbPo", | ||
}, | ||
}, | ||
}, TC{ | ||
src: ipld.Node{ | ||
"foo": "bar", | ||
"bar": []int{1, 2, 3}, | ||
"@container": "@index", | ||
"@index": "links", | ||
"baz": ipld.Node{ | ||
"mlink": "QmZku7P7KeeHAnwMr6c4HveYfMzmtVinNXzibkiNbfDbPo", | ||
}, | ||
}, | ||
jsonld: ipld.Node{ | ||
"links": ipld.Node{ | ||
"foo": "bar", | ||
"bar": []int{1, 2, 3}, | ||
"baz": ipld.Node{ | ||
"mlink": "QmZku7P7KeeHAnwMr6c4HveYfMzmtVinNXzibkiNbfDbPo", | ||
}, | ||
}, | ||
}, | ||
}, TC{ | ||
src: ipld.Node{ | ||
"@attrs": ipld.Node{ | ||
"attr": "val", | ||
}, | ||
"foo": "bar", | ||
"@index": "files", | ||
"@type": "commit", | ||
"@container": "@index", | ||
"@context": "/ipfs/QmZku7P7KeeHAnwMr6c4HveYfMzmtVinNXzibkiNbfDbPo/mdag", | ||
"baz": ipld.Node{ | ||
"foobar": "barfoo", | ||
"mlink": "QmZku7P7KeeHAnwMr6c4HveYfMzmtVinNXzibkiNbfDbPo", | ||
}, | ||
"\\@bazz": ipld.Node{ | ||
"mlink": "QmZku7P7KeeHAnwMr6c4HveYfMzmtVinNXzibkiNbfDbPo", | ||
}, | ||
"bar/ra\\b": ipld.Node{ | ||
"mlink": "QmZku7P7KeeHAnwMr6c4HveYfMzmtVinNXzibkiNbfDbPb", | ||
}, | ||
"bar": ipld.Node{ | ||
"@container": "@index", | ||
"foo": ipld.Node{ | ||
"mlink": "QmZku7P7KeeHAnwMr6c4HveYfMzmtVinNXzibkiNbfDbPa", | ||
}, | ||
}, | ||
}, | ||
jsonld: ipld.Node{ | ||
"attr": "val", | ||
"@type": "commit", | ||
"@context": "/ipfs/QmZku7P7KeeHAnwMr6c4HveYfMzmtVinNXzibkiNbfDbPo/mdag", | ||
"files": ipld.Node{ | ||
"foo": "bar", | ||
"baz": ipld.Node{ | ||
"foobar": "barfoo", | ||
"mlink": "QmZku7P7KeeHAnwMr6c4HveYfMzmtVinNXzibkiNbfDbPo", | ||
}, | ||
"@bazz": ipld.Node{ | ||
"mlink": "QmZku7P7KeeHAnwMr6c4HveYfMzmtVinNXzibkiNbfDbPo", | ||
}, | ||
"bar/ra\\b": ipld.Node{ | ||
"mlink": "QmZku7P7KeeHAnwMr6c4HveYfMzmtVinNXzibkiNbfDbPb", | ||
}, | ||
"bar": ipld.Node{ | ||
}, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestParsing(t *testing.T) { | ||
for tci, tc := range testCases { | ||
t.Logf("===== Test case #%d =====", tci) | ||
doc := tc.src | ||
|
||
// check JSON-LD mode | ||
jsonld := ToLinkedDataAll(doc) | ||
if !reflect.DeepEqual(tc.jsonld, jsonld) { | ||
t.Errorf("JSON-LD version mismatch.\nGot: %#v\nExpect: %#v", jsonld, tc.jsonld) | ||
} else { | ||
t.Log("JSON-LD version OK") | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package jsonld | ||
|
||
import( | ||
ipld "github.com/ipfs/go-ipld" | ||
) | ||
|
||
const DefaultIndexName string = "@index" | ||
|
||
func ContainerIndexName(n ipld.Node, defaultval string) string { | ||
var index_name string = defaultval | ||
|
||
index_val, ok := n["@index"] | ||
if str, is_string := index_val.(string); ok && is_string { | ||
index_name = str | ||
} | ||
|
||
return index_name | ||
} | ||
|
||
// Like ToLinkedDataAll but on the root node only, for use in Walk | ||
func ToLinkedData(d ipld.Node) ipld.Node { | ||
attrs, directives, _, index := ipld.ParseNodeIndex(d) | ||
for k, v := range directives { | ||
if k != "@container" { | ||
attrs[k] = v | ||
} | ||
} | ||
if len(index) > 0 { | ||
index_name := ipld.ContainerIndexName(attrs, ipld.DefaultIndexName) | ||
delete(attrs, "@index") | ||
if index_name[0] != '@' { | ||
attrs[index_name] = index | ||
} | ||
} | ||
return attrs | ||
} | ||
|
||
// Reorganize the data to be valid JSON-LD. This expand custom IPLD directives | ||
// and unescape keys. | ||
// | ||
// The main processing now is to transform a IPLD data structure like this: | ||
// | ||
// { | ||
// "@container": "@index", | ||
// "@index": "index-name", | ||
// "@attrs": { | ||
// "key": "value", | ||
// }, | ||
// "index": { ... } | ||
// } | ||
// | ||
// to: | ||
// | ||
// { | ||
// "key": "value", | ||
// "index-name": { | ||
// "index": { ... } | ||
// } | ||
// } | ||
// | ||
// In that case, it is good practice to define in the context the following | ||
// type (this function cannot change the context): | ||
// | ||
// "index-name": { "@container": "@index" } | ||
// | ||
func ToLinkedDataAll(d ipld.Node) ipld.Node { | ||
res, err := ipld.Transform(d, func(root, curr ipld.Node, path []string, err error) (ipld.Node, error) { | ||
return ToLinkedData(curr), err | ||
}) | ||
if err != nil { | ||
panic(err) // should not happen | ||
} | ||
return res | ||
} | ||
|
Oops, something went wrong.