Commit 697dcc0
Changed files (4)
lib/scim/kit/v2/parser.rb
@@ -0,0 +1,74 @@
+# frozen_string_literal: true
+require 'parslet'
+
+module Scim
+ module Kit
+ module V2
+=begin
+FILTER = attrExp / logExp / valuePath / *1"not" "(" FILTER ")"
+
+valuePath = attrPath "[" valFilter "]"
+ ; FILTER uses sub-attributes of a parent attrPath
+
+valFilter = attrExp / logExp / *1"not" "(" valFilter ")"
+
+attrExp = (attrPath SP "pr") /
+ (attrPath SP compareOp SP compValue)
+
+logExp = FILTER SP ("and" / "or") SP FILTER
+
+compValue = false / null / true / number / string
+ ; rules from JSON (RFC 7159)
+
+compareOp = "eq" / "ne" / "co" /
+ "sw" / "ew" /
+ "gt" / "lt" /
+ "ge" / "le"
+
+attrPath = [URI ":"] ATTRNAME *1subAttr
+ ; SCIM attribute name
+ ; URI is SCIM "schema" URI
+
+ATTRNAME = ALPHA *(nameChar)
+
+nameChar = "-" / "_" / DIGIT / ALPHA
+
+subAttr = "." ATTRNAME
+ ; a sub-attribute of a complex attribute
+=end
+ class Parser < Parslet::Parser
+ rule(:lparen) { str('(') >> space? }
+ rule(:rparen) { str(')') >> space? }
+ rule(:digit) { match(/\d/) }
+ rule(:quote) { str('"') }
+ rule(:space) { match('\s').repeat(1) }
+ rule(:space?) { space.maybe }
+
+ rule(:attribute) { match['a-zA-Z\.'].repeat(1) }
+
+ rule(:operator) { equal | not_equal | contains | starts_with | ends_with | greater_than | less_than | less_than_equals | greater_than_equals }
+ rule(:equal) { str("eq") }
+ rule(:not_equal) { str("ne") }
+ rule(:contains) { str("co") }
+ rule(:starts_with) { str("sw") }
+ rule(:ends_with) { str("ew") }
+ rule(:greater_than) { str("gt") }
+ rule(:less_than) { str("lt") }
+ rule(:greater_than_equals) { str("ge") }
+ rule(:less_than_equals) { str("le") }
+
+ rule(:quoted_value) { quote >> value.as(:right) >> quote }
+ rule(:value) { match(/[a-zA-Z0-9:\-]/).repeat(1) }
+
+ rule(:filter) { attribute.as(:left) >> space >> operator.as(:operator) >> space >> quoted_value }
+ root :filter
+
+ def pretty_parse(*args)
+ parse(*args)
+ rescue Parslet::ParseFailed => error
+ puts error.parse_failure_cause.ascii_tree
+ end
+ end
+ end
+ end
+end
lib/scim/kit/v2.rb
@@ -11,6 +11,7 @@ require 'scim/kit/v2/meta'
require 'scim/kit/v2/mutability'
require 'scim/kit/v2/resource'
require 'scim/kit/v2/error'
+require 'scim/kit/v2/parser'
require 'scim/kit/v2/resource_type'
require 'scim/kit/v2/returned'
require 'scim/kit/v2/schema'
spec/scim/kit/v2/parser_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+RSpec.describe Scim::Kit::V2::Parser do
+ subject { described_class.new }
+
+ context "simple expression" do
+ let(:expression) { %Q(userName eq "bjensen") }
+ let(:result) { subject.pretty_parse(expression) }
+
+ specify { expect(result).to be_present }
+ specify { expect(result[:left].to_s).to eql('userName') }
+ specify { expect(result[:operator].to_s).to eql('eq') }
+ specify { expect(result[:right].to_s).to eql('bjensen') }
+ end
+end
scim-kit.gemspec
@@ -32,6 +32,7 @@ Gem::Specification.new do |spec|
spec.add_dependency 'activemodel', '>= 5.2.0'
spec.add_dependency 'net-hippie', '~> 0.2'
+ spec.add_dependency 'parslet', '~> 1.8'
spec.add_dependency 'tilt', '~> 2.0'
spec.add_dependency 'tilt-jbuilder', '~> 0.7'
spec.add_development_dependency 'bundler', '~> 1.17'