mirror of
https://github.com/flynx/diff.js.git
synced 2025-10-28 18:40:09 +00:00
added object path writer/reader...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
1013af0e47
commit
1ad987190d
142
diff2.js
142
diff2.js
@ -34,6 +34,12 @@ var types = require('ig-types')
|
|||||||
//
|
//
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
|
||||||
|
var EMPTY =
|
||||||
|
module.EMPTY =
|
||||||
|
//Symbol.EMPTY =
|
||||||
|
Symbol('EMPTY')
|
||||||
|
|
||||||
|
|
||||||
// XXX need a way to uniquely serilaize this to a string path...
|
// XXX need a way to uniquely serilaize this to a string path...
|
||||||
// ...or some other way to use it in a convinient manner...
|
// ...or some other way to use it in a convinient manner...
|
||||||
var CONTENT =
|
var CONTENT =
|
||||||
@ -344,7 +350,9 @@ var serializePathElem = function(p, i, l){
|
|||||||
: typeof(p) == 'string' ?
|
: typeof(p) == 'string' ?
|
||||||
p.replace(/([\/:])/g, '\\$1')
|
p.replace(/([\/:])/g, '\\$1')
|
||||||
: p }
|
: p }
|
||||||
var serializePath = function(p){
|
var path2str =
|
||||||
|
module.path2str =
|
||||||
|
function(p){
|
||||||
return '/'+ p
|
return '/'+ p
|
||||||
.map(serializePathElem)
|
.map(serializePathElem)
|
||||||
.reduce(function(res, e){
|
.reduce(function(res, e){
|
||||||
@ -354,34 +362,35 @@ var serializePath = function(p){
|
|||||||
res.push(e)
|
res.push(e)
|
||||||
return res }, [])
|
return res }, [])
|
||||||
.join('/') }
|
.join('/') }
|
||||||
/*/ XXX might also be a good idea to serialize the path into an
|
|
||||||
// arbitrary length as we always have exactly one value, e.g.:
|
|
||||||
// [ '/path/to/map', 'CONTENT', 'path/in/content', 123]
|
// XXX do we handle @key here???
|
||||||
var serializePathElem = function(p, i, l){
|
var deserializePathElem = function(p){
|
||||||
return typeof(p) == 'object' ?
|
return /[^\\]:CONTENT$/.test(p) ?
|
||||||
JSON.stringify(p)
|
[p.replace(/(?<!\\):CONTENT$/, ''), module.CONTENT]
|
||||||
// quote special chars...
|
: [p] }
|
||||||
: typeof(p) == 'string' ?
|
// XXX should we hanve relative paths????
|
||||||
p.replace(/([\/])/g, '\\$1')
|
var str2path =
|
||||||
: p }
|
module.str2path =
|
||||||
var serializePath = function(p){
|
function(str){
|
||||||
return p
|
return str instanceof Array ?
|
||||||
.map(serializePathElem)
|
str
|
||||||
.reduce(function(res, e){
|
: (str
|
||||||
e === module.CONTENT ?
|
.replace(/^\//, '')
|
||||||
res.splice(res.length, 0, 'CONTENT', '')
|
.split(/\//g)
|
||||||
: (res[res.length-1] += '/'+ e)
|
.map(deserializePathElem)
|
||||||
return res }, ['']) }
|
.flat()) }
|
||||||
//*/
|
|
||||||
|
|
||||||
var serializePaths =
|
var serializePaths =
|
||||||
module.serializePaths =
|
module.serializePaths =
|
||||||
types.generator.iter
|
types.generator.iter
|
||||||
.map(function([p, v]){
|
.map(function([p, v]){
|
||||||
return v instanceof Array && v[0] == 'LINK' ?
|
return v instanceof Array && v[0] == 'LINK' ?
|
||||||
// link...
|
// link...
|
||||||
[serializePath(p),
|
[path2str(p),
|
||||||
'LINK', serializePath(v[1])]
|
'LINK', path2str(v[1])]
|
||||||
: [serializePath(p), v] })
|
: [path2str(p), v] })
|
||||||
|
|
||||||
|
|
||||||
// remove attributes from object metadata...
|
// remove attributes from object metadata...
|
||||||
@ -414,6 +423,93 @@ function(...attrs){
|
|||||||
// XXX construct...
|
// XXX construct...
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// atPath(root, path)
|
||||||
|
// -> value
|
||||||
|
//
|
||||||
|
// atPath(root, path, value)
|
||||||
|
// -> value
|
||||||
|
//
|
||||||
|
// NOTE: to set this needs the full basepath to exist...
|
||||||
|
//
|
||||||
|
// XXX overcomplicated...
|
||||||
|
// XXX add support for deleting / writeing EMPTY
|
||||||
|
var atPath =
|
||||||
|
module.atPath =
|
||||||
|
function(root, path, value){
|
||||||
|
path = str2path(path)
|
||||||
|
// get value at path...
|
||||||
|
var content = false
|
||||||
|
var base
|
||||||
|
var target = path
|
||||||
|
.reduce(function(cur, p){
|
||||||
|
// CONTENT...
|
||||||
|
if(p === module.CONTENT){
|
||||||
|
// NOTE: indicate to the next iteration that we'll need
|
||||||
|
// to use map/set API to get/set the value...
|
||||||
|
content = true
|
||||||
|
base = cur
|
||||||
|
return cur }
|
||||||
|
// value in content...
|
||||||
|
if(content){
|
||||||
|
return cur instanceof Set ?
|
||||||
|
[...cur][p]
|
||||||
|
// map key...
|
||||||
|
: p.slice(-4) == '@key' ?
|
||||||
|
[...cur][p.slice(0, -4)][0]
|
||||||
|
// map value...
|
||||||
|
: [...cur][p][1] }
|
||||||
|
content = false
|
||||||
|
base = cur
|
||||||
|
return cur[p] }, root)
|
||||||
|
|
||||||
|
// get...
|
||||||
|
if(arguments.length <= 2){
|
||||||
|
return target }
|
||||||
|
|
||||||
|
// write attr...
|
||||||
|
if(!content){
|
||||||
|
value === module.EMPTY ?
|
||||||
|
(delete base[path.last()])
|
||||||
|
: (base[path.last()] = value)
|
||||||
|
// XXX should we return value or base???
|
||||||
|
// ...should we return target when writing EMPTY
|
||||||
|
return value}
|
||||||
|
|
||||||
|
var index = path.last()
|
||||||
|
// write set item...
|
||||||
|
if(base instanceof Set){
|
||||||
|
value === module.EMPTY ?
|
||||||
|
base.delete(target)
|
||||||
|
:index == base.size ?
|
||||||
|
base.add(value)
|
||||||
|
: base.replaceAt(index, value)
|
||||||
|
// XXX should we return value or base???
|
||||||
|
// ...should we return target when writing EMPTY
|
||||||
|
return value }
|
||||||
|
|
||||||
|
// write map item/key...
|
||||||
|
var isKey = index.slice(-4) == '@key'
|
||||||
|
index = isKey ?
|
||||||
|
index.slice(0, -4)
|
||||||
|
: index
|
||||||
|
var key = atPath(root,
|
||||||
|
path
|
||||||
|
.slice(0,-1)
|
||||||
|
.concat([index +'@key']))
|
||||||
|
value === module.EMPTY ?
|
||||||
|
base.delete(key)
|
||||||
|
: isKey ?
|
||||||
|
base.replaceKey(key, value)
|
||||||
|
: base.set(key, value)
|
||||||
|
|
||||||
|
// XXX should we return value or base???
|
||||||
|
// ...should we return target when writing EMPTY
|
||||||
|
return value }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user