traipse 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in traipse.gemspec
4
+ gemspec
5
+ gem 'rspec'
@@ -0,0 +1,33 @@
1
+ = Traipse
2
+
3
+ Traipse allows you to address a data structure with a dot notated string. This is useful for extracting certain nodes
4
+ in a data structure (expecially JSON-parsed) and storing the 'path' to those nodes in a database.
5
+
6
+ == Installation
7
+
8
+ Traipse is available as a RubyGem:
9
+
10
+ gem install traipse
11
+
12
+ === Example
13
+
14
+ data = {
15
+ "name" => "Percival",
16
+ "board" => {
17
+ "name" => "cats"
18
+ },
19
+ "categories" => [
20
+ { "name" => "animals" },
21
+ { "name" => "kitties" },
22
+ { "name" => "robots" },
23
+ ]
24
+ }
25
+
26
+ Traipse.find( data, 'name' ) # [ "Percival" ]
27
+ Traipse.find( data, 'board.name' ) # [ "cats" ]
28
+ Traipse.find( data, 'categories.name' ) # [ "animals", "kitties", "robots" ]
29
+ Traipse.find( data, '*.name' ) # [ "cats", "animals", "kitties", "robots" ]
30
+
31
+ == Authors
32
+
33
+ * Pawel Szymczykowski
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,46 @@
1
+ require "traipse/version"
2
+
3
+ module Traipse
4
+
5
+ SEPARATOR = '.'
6
+
7
+ # Find a needle in a haystack using something akin to JSON dot syntax
8
+ # ex: Traipse.find( data, 'cat.name' ) # similar to data['cat']['name']
9
+ def self.find( object, path )
10
+ return _find( object, path.split( SEPARATOR ) )
11
+ end
12
+
13
+ def self._find( object, path, results=[] ) # :nodoc:
14
+ key, *rest = path
15
+
16
+ # Oops.. no key? Hands a path of '*'
17
+ return [ object ] unless key
18
+
19
+ # What happens if we miss a key?
20
+ return [] unless object.is_a?( Hash )
21
+
22
+ # Handle wildcard hash keys
23
+ if key == '*'
24
+ object.keys.each do |subkey|
25
+ results += _find( object, [ subkey, *rest ] )
26
+ end
27
+ return results
28
+ end
29
+
30
+ # This is the end of the line, megatron.
31
+ return [ object[ key ] ].compact if rest.empty?
32
+
33
+ # Traverse hashes and arrays
34
+ case object[ key ]
35
+ when Hash
36
+ return _find( object[ key ], rest )
37
+ when Array
38
+ object[ key ].each do |obj|
39
+ results += _find( obj, rest )
40
+ end
41
+ end
42
+
43
+ return results
44
+ end
45
+
46
+ end
@@ -0,0 +1,3 @@
1
+ module Traipse
2
+ VERSION = "0.5.0"
3
+ end
@@ -0,0 +1,7 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'traipse'
5
+
6
+ RSpec.configure do |config|
7
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ data = {
4
+ "name" => "Percival",
5
+ "board" => {
6
+ "name" => "cats"
7
+ },
8
+ "categories" => [
9
+ { "name" => "animals" },
10
+ { "name" => "kitties" },
11
+ { "name" => "robots" },
12
+ ],
13
+ "products" => [
14
+ "shoes" => {
15
+ "brands" => [
16
+ { "name" => "converse" },
17
+ { "name" => "adidas" },
18
+ { "name" => "nike" }
19
+ ]
20
+ },
21
+ "apparel" => {
22
+ "brands" => [
23
+ { "name" => "Calvin Klein" },
24
+ { "name" => "Diesel" },
25
+ { "name" => "Betsey Johnson" },
26
+ { "name" => [ "Marc", "Ecko" ] },
27
+ { "caltrops" => 'Yes Please' }
28
+ ]
29
+ }
30
+ ]
31
+ };
32
+
33
+ describe Traipse do
34
+
35
+ it "can find top level values" do
36
+ Traipse.find( data, 'name' ).should == [ 'Percival' ]
37
+ end
38
+
39
+ it "can get to nested values" do
40
+ Traipse.find( data, 'board.name' ).should == [ 'cats' ]
41
+ end
42
+
43
+ it "can traverse arrays" do
44
+ Traipse.find( data, 'categories.name' ).should == [ "animals", "kitties", "robots" ]
45
+ end
46
+
47
+ it "can traverse arrays to get to nested values" do
48
+ Traipse.find( data, 'products.shoes.brands.name' ).should ==
49
+ [ "converse", "adidas", "nike" ]
50
+ end
51
+
52
+ it "can handle key wildcards" do
53
+ Traipse.find( data, 'products.*.brands.name' ).should ==
54
+ [ "converse", "adidas", "nike", "Calvin Klein",
55
+ "Diesel", "Betsey Johnson", [ "Marc", "Ecko" ] ]
56
+
57
+ Traipse.find( data, '*.name' ).should == [ "cats", "animals", "kitties", "robots" ]
58
+ end
59
+
60
+ it "can do multiple wildcards" do
61
+ Traipse.find( data, "products.*.brands.*" ).should ==
62
+ [ "converse", "adidas", "nike", "Calvin Klein",
63
+ "Diesel", "Betsey Johnson", [ "Marc", "Ecko" ], 'Yes Please' ]
64
+ end
65
+
66
+ end
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "traipse/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "traipse"
7
+ s.version = Traipse::VERSION
8
+ s.authors = ["Pawel Szymczykowski"]
9
+ s.email = ["makenai@gmail.com"]
10
+ s.homepage = "https://github.com/makenai/traipse"
11
+ s.summary = %q{Traverse data structures with a dot notated string.}
12
+ s.description = %q{Traipse is a library that allows you to address a data structure of Hashes & Arrays using a dot notated string & wildcards. ex: 'categories.*.name'. Like X-Path but dumber.}
13
+
14
+ s.rubyforge_project = "traipse"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: traipse
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Pawel Szymczykowski
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-25 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: ! 'Traipse is a library that allows you to address a data structure of
15
+ Hashes & Arrays using a dot notated string & wildcards. ex: ''categories.*.name''.
16
+ Like X-Path but dumber.'
17
+ email:
18
+ - makenai@gmail.com
19
+ executables: []
20
+ extensions: []
21
+ extra_rdoc_files: []
22
+ files:
23
+ - .gitignore
24
+ - Gemfile
25
+ - README.rdoc
26
+ - Rakefile
27
+ - lib/traipse.rb
28
+ - lib/traipse/version.rb
29
+ - spec/spec_helper.rb
30
+ - spec/traipse_spec.rb
31
+ - traipse.gemspec
32
+ homepage: https://github.com/makenai/traipse
33
+ licenses: []
34
+ post_install_message:
35
+ rdoc_options: []
36
+ require_paths:
37
+ - lib
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ none: false
46
+ requirements:
47
+ - - ! '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ requirements: []
51
+ rubyforge_project: traipse
52
+ rubygems_version: 1.8.17
53
+ signing_key:
54
+ specification_version: 3
55
+ summary: Traverse data structures with a dot notated string.
56
+ test_files:
57
+ - spec/spec_helper.rb
58
+ - spec/traipse_spec.rb