class Xjson
require 'byebug'
Constants
- VERSION
Attributes
data[R]
dir[R]
ext_data[R]
Public Class Methods
load( filename )
click to toggle source
# File lib/xjson.rb, line 14 def Xjson.load( filename ) Marshal.load( File.read( filename ) ) end
new( xjson_file )
click to toggle source
# File lib/xjson.rb, line 22 def initialize( xjson_file ) @cur_file = [] @cur_data = [] @ext_data = {} @ext_data = read_json_file( xjson_file ) @data = expand( @ext_data ) end
version()
click to toggle source
# File lib/xjson.rb, line 10 def Xjson.version Xjson::VERSION end
Public Instance Methods
dump( filename )
click to toggle source
# File lib/xjson.rb, line 264 def dump( filename ) File.write( filename, Marshal.dump( @data ) ) end
expand( data )
click to toggle source
Expand json recursively.
# File lib/xjson.rb, line 153 def expand( data ) case data when TrueClass; data when FalseClass; data when Float; data when Integer; data when String; data when Array; ret = [] @cur_data.unshift ret data.each do |v| value = expand( v ) ret.push( value ) if value end @cur_data.shift ret when Hash if data.size == 1 # Most possible extension. k, v = data.first case k when "@eval" %x"#{expand(v)}".split("\n") when "@env" ENV[expand(v)] when "@join" flatten( v[1..-1].map{|i| expand( i )} ).join( v[0] ) when "@flat" flatten( v[1..-1].map{|i| expand( i )} ) when "@self" reference( @ext_data, expand(v) ) when "@over"; override( @cur_data[0], expand(v), true ) nil when "@base"; override( @cur_data[0], expand(v), false ) nil when "@null" nil when "@include"; jsonfile = expand(v) subdata = read_json_file( jsonfile ) expdata = expand( subdata ) if expdata.class == Hash if @cur_data[0].class == expdata.class expdata.each do |ke,ve| @cur_data[0][ ke ] = ve end else raise XjsonIncludeError, "Included file (\"#{jsonfile}\") must contain a hash as top level" end elsif expdata.class == Array expdata.each do |ve| @cur_data[0].push ve end else raise XjsonIncludeError, "Included file (\"#{jsonfile}\") must contain a hash or a an array as top level" end @cur_file.shift nil else # Non-extension. { k => expand( v ) } end else ret = {} @cur_data.unshift ret data.each do |k,v| case k when "@null"; nil else value = expand( v ) ret[ k ] = value if value end end @cur_data.shift ret end end end
find_in_array_of_hash( scope, key, value )
click to toggle source
# File lib/xjson.rb, line 57 def find_in_array_of_hash( scope, key, value ) index = 0 while index < scope.length if Regexp.new( value).match( scope[ index ][ key ] ) return index end index += 1 end nil end
flatten( data )
click to toggle source
Flatten by one level within array.
# File lib/xjson.rb, line 40 def flatten( data ) case data when Array; res = [] data.each do |i| if i.class == Array res += i else res.push i end end res else data end end
override( data, exp, overwrite = false )
click to toggle source
# File lib/xjson.rb, line 146 def override( data, exp, overwrite = false ) desc = override_desc( data, exp ) override_apply( desc, overwrite ) end
override_apply( desc, overwrite = false )
click to toggle source
# File lib/xjson.rb, line 131 def override_apply( desc, overwrite = false ) if desc[:label] == "*" desc[:path].each do |place| if not( place[ desc[:value][0] ] ) || overwrite place[ desc[:value][0] ] = desc[:value][1] end end else if not( desc[:path][desc[:label]] ) || overwrite desc[:path][desc[:label]] = desc[:value] end end end
override_desc( data, exp )
click to toggle source
# File lib/xjson.rb, line 125 def override_desc( data, exp ) path, label = reference_handle( data, exp[0] ) { path: path, label: label, value: exp[1] } end
read_json_file( xjson_file )
click to toggle source
# File lib/xjson.rb, line 30 def read_json_file( xjson_file ) @cur_file.unshift xjson_file if xjson_file[0] != "<" JSON.parse( File.read( xjson_file ) ) else JSON.parse( STDIN.read ) end end
reference( data, ref_desc )
click to toggle source
# File lib/xjson.rb, line 108 def reference( data, ref_desc ) path, label = reference_handle( data, ref_desc ) begin index = Integer( label ) scope = path[ index ] rescue # scope = scope[ path[0] ] scope = path[ label ] end # scope = path[ label ] # if scope.class == String scope # else # scope.to_s # end end
reference_handle( data, ref_desc )
click to toggle source
# File lib/xjson.rb, line 68 def reference_handle( data, ref_desc ) if ref_desc[0] != ":" # [ data, ref_desc ] reference_handle( data, ":#{ref_desc}" ) else # Relative reference from root. path = ref_desc.split( ":" )[1..-1] scope = data while path[0..-2].any? if path[0] == "*" # Wildcard for array. unless path[1] && path[2] raise XjsonReferenceError, "Invalid reference: \"#{ref_desc}\" in \"#{@cur_file[0]}\", missing match key and value ..." end index = find_in_array_of_hash( scope, path[1], path[2] ) unless index raise XjsonReferenceError, "Invalid reference: \"#{ref_desc}\" in \"#{@cur_file[0]}\", key and value not matched ..." end scope = scope[ index ] path.shift( 2 ) else begin index = Integer( path[0] ) scope = scope[ index ] rescue scope = scope[ path[0] ] end end path.shift unless scope raise XjsonReferenceError, "Invalid reference: \"#{ref_desc}\" in \"#{@cur_file[0]}\"..." end end [ scope, path[-1] ] end end
to_s()
click to toggle source
# File lib/xjson.rb, line 260 def to_s JSON.pretty_generate( @data ) end