Skip to content

Commit

Permalink
Merge pull request #39 from ivixvi/refactor-main-functions
Browse files Browse the repository at this point in the history
Refactor main functions
  • Loading branch information
ivixvi authored Feb 11, 2025
2 parents e21e9b6 + 23e46c9 commit 313a07a
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 56 deletions.
9 changes: 0 additions & 9 deletions adder.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,6 @@ func (r *adder) addValue(scopedMap map[string]interface{}, scopedAttr string, ne
return false
}

func (r *adder) ByValueForItem(scopedSlice []interface{}, value interface{}) ([]interface{}, bool) {
changed := false
if !containsItem(scopedSlice, value) {
changed = true
scopedSlice = append(scopedSlice, value)
}
return scopedSlice, changed
}

func (r *adder) ByValueExpressionForItem(scopedMaps []map[string]interface{}, expr filter.Expression, value interface{}) ([]map[string]interface{}, bool) {
newValue, ok := value.(map[string]interface{})

Expand Down
3 changes: 1 addition & 2 deletions operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ import "github.com/scim2/filter-parser/v2"
// Operator は Patch Operation の各操作のドメインとなるインターフェースです。
// Direct は map とその map 内で更新対象となる属性と更新後の値を受け取って更新後のmapと変更有無を返却します
// この関数のみ、pathが未指定の場合でも利用されます
// ByValueForItem は path が指定されているときに、MultiValued な属性名が指定されたとき対象のスライスと指定された値を受け取って、更新後のスライスと変更有無を返却します。
// ByValueExpressionForItem は 対象の属性が、MultiValuedComplexAttribute で path にて valFilter が指定されているときにそれを受けとって更新後のスライスと変更有無を返却します。
// ByValueExpressionForAttribute は 対象の属性が、MultiValuedComplexAttribute で path にて valFilter と subAttr が指定されているときにそれを受けとって更新後のスライスと変更有無を返却します。
type Operator interface {
Direct(scopedMap map[string]interface{}, scopedAttr string, value interface{}) bool
ByValueForItem(scopedSlice []interface{}, value interface{}) ([]interface{}, bool)

ByValueExpressionForItem(scopedMaps []map[string]interface{}, expr filter.Expression, value interface{}) ([]map[string]interface{}, bool)
ByValueExpressionForAttribute(scopedMaps []map[string]interface{}, expr filter.Expression, subAttr string, value interface{}) ([]map[string]interface{}, bool)
}
13 changes: 0 additions & 13 deletions remover.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,6 @@ func (r *remover) Direct(scopedMap map[string]interface{}, scopedAttr string, va
return false
}

func (r *remover) ByValueForItem(scopedSlice []interface{}, value interface{}) ([]interface{}, bool) {
changed := false
newValues := []interface{}{}
for _, oldValue := range scopedSlice {
if oldValue != value {
newValues = append(newValues, oldValue)
} else {
changed = true
}
}
return newValues, changed
}

func (r *remover) ByValueExpressionForItem(scopedMaps []map[string]interface{}, expr filter.Expression, value interface{}) ([]map[string]interface{}, bool) {
changed := false
newValues := []map[string]interface{}{}
Expand Down
9 changes: 0 additions & 9 deletions replacer.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,6 @@ func (r *replacer) replaceValue(scopedMap map[string]interface{}, scopedAttr str
return false
}

func (r *replacer) ByValueForItem(scopedSlice []interface{}, value interface{}) ([]interface{}, bool) {
changed := false
if !containsItem(scopedSlice, value) {
changed = true
scopedSlice = append(scopedSlice, value)
}
return scopedSlice, changed
}

func (r *replacer) ByValueExpressionForItem(scopedMaps []map[string]interface{}, expr filter.Expression, value interface{}) ([]map[string]interface{}, bool) {
newValue, ok := value.(map[string]interface{})

Expand Down
46 changes: 23 additions & 23 deletions scimpatch.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,16 +141,19 @@ func (p *Patcher) pathSpecifiedOperate(
}
n := newScopeNavigator(op, data, attr)
switch {
// request path is `attr[expr].subAttr`
case attr.MultiValued() && op.Path.ValueExpression != nil && op.Path.SubAttribute != nil:
var newValues []map[string]interface{}
oldValues := n.GetScopedMapSlice()
newValues, changed = operator.ByValueExpressionForAttribute(oldValues, op.Path.ValueExpression, *op.Path.SubAttribute, op.Value)
n.ApplyScopedMapSlice(newValues)
// request path is `attr[expr]`
case attr.MultiValued() && op.Path.ValueExpression != nil:
var newValues []map[string]interface{}
oldValues := n.GetScopedMapSlice()
newValues, changed = operator.ByValueExpressionForItem(oldValues, op.Path.ValueExpression, op.Value)
n.ApplyScopedMapSlice(newValues)
// request path is `attr`, `attr.subAttr`
case !attr.MultiValued() || op.Path.ValueExpression == nil:
scopedMap, scopedAttr := n.GetScopedMap()
changed = operator.Direct(scopedMap, scopedAttr, op.Value)
Expand All @@ -170,29 +173,26 @@ func (p *Patcher) pathUnspecifiedOperate(
changed := false
for attr, value := range newMap {
uriPrefix, ok := p.schemas[attr]
if ok {
oldMap, ok := data[uriPrefix.ID].(map[string]interface{})
if !ok {
changed = true
data[uriPrefix.ID] = value
} else {
newUriMap, ok := value.(map[string]interface{})
if !ok {
// unexpected input
continue
}
for scopedAttr, scopedValue := range newUriMap {
changed_ := operator.Direct(oldMap, scopedAttr, scopedValue)
if changed_ {
changed = changed_ || changed
}
}
data[uriPrefix.ID] = oldMap
}
} else {
changed_ := operator.Direct(data, attr, value)
if changed_ {
changed = changed_ || changed
// Core Attributes
if !ok {
changed = changed || operator.Direct(data, attr, value)
continue
}

// Schema Extension Attributes
oldMap, ok := data[uriPrefix.ID].(map[string]interface{})

// if not exists, write all attributes
if !ok {
changed = true
data[uriPrefix.ID] = value
continue
}

// if exists, write by every attributes
if newUriMap, ok := value.(map[string]interface{}); ok {
for scopedAttr, scopedValue := range newUriMap {
changed = changed || operator.Direct(oldMap, scopedAttr, scopedValue)
}
}
}
Expand Down

0 comments on commit 313a07a

Please sign in to comment.