Skip to content

Commit

Permalink
Add filter middleware for simpler logic
Browse files Browse the repository at this point in the history
  • Loading branch information
deanishe committed Jan 27, 2018
1 parent e2e756d commit 8027144
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 11 deletions.
36 changes: 36 additions & 0 deletions filter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//
// Copyright (c) 2018 Dean Jackson <[email protected]>
//
// MIT Licence. See http://opensource.org/licenses/MIT
//
// Created on 2018-01-27
//

package main

// Filterer passes selectively passes through strings
type Filterer func(in <-chan string) <-chan string

// Filter is a chain of Filterers
type Filter struct {
Funcs []Filterer
}

// Use adds a Filterer to the stack
func (f *Filter) Use(fn Filterer) {
f.Funcs = append(f.Funcs, fn)
}

// Apply runs the filter on a channel.
func (f *Filter) Apply(in <-chan string) <-chan string {

var out = make(<-chan string)

// Make stack of handlers
out = f.Funcs[len(f.Funcs)-1](in)
for i := len(f.Funcs) - 2; i >= 0; i-- {
out = f.Funcs[i](out)
}

return out
}
87 changes: 87 additions & 0 deletions filter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
//
// Copyright (c) 2018 Dean Jackson <[email protected]>
//
// MIT Licence. See http://opensource.org/licenses/MIT
//
// Created on 2018-01-27
//

package main

import (
"path/filepath"
"testing"
)

func TestFilter(t *testing.T) {
data := []struct {
in, out []string
}{
{[]string{""}, []string{}},
{[]string{"file", "file.txt"}, []string{"file.txt"}},
{[]string{"file.txt", "file.pdf"}, []string{"file.txt", "file.pdf"}},
{[]string{"file.mp4", "file.pdf"}, []string{"file.pdf"}},
}

for _, td := range data {

var in = make(chan string)

// Generate input
go func(c chan string, data []string) {

for _, s := range data {
if s == "" {
continue
}
x := filepath.Ext(s)
if x == ".mp4" || x == "" {
continue
}
c <- s
}
close(in)
}(in, td.in)

f := Filter{}
f.Use(func(in <-chan string) <-chan string {
var out = make(chan string)

go func() {
defer close(out)

for s := range in {
out <- s
}

}()

return out
})

out := f.Apply(in)
res := []string{}
for s := range out {
res = append(res, s)
}

if !strSlicesEqual(res, td.out) {
t.Errorf("Bad Filter. Expected=%#v, Got=%#v", td.out, res)
}
}

}

func strSlicesEqual(s1, s2 []string) bool {
if len(s1) != len(s2) {
return false
}

for i, s := range s1 {
if s != s2[i] {
return false
}
}

return true
}
24 changes: 13 additions & 11 deletions scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func scan() <-chan Project {
var (
ins []<-chan string
out = make(<-chan Project)
f = &Filter{}
)

for name, scanner := range scanners {
Expand All @@ -71,17 +72,12 @@ func scan() <-chan Project {
}

// real programs have middleware
out = resultToProject(
filterExcludes(
filterNotExist(
filterDupes(
filterNotProject(
merge(ins...),
),
),
),
conf.Excludes),
)
f.Use(makeFilterExcludes(conf.Excludes))
f.Use(filterNotExist)
f.Use(filterDupes)
f.Use(filterNotProject)

out = resultToProject(f.Apply(merge(ins...)))

return out
}
Expand Down Expand Up @@ -271,6 +267,12 @@ func lineCommand(cmd *exec.Cmd, name string) (chan string, error) {
return out, err
}

func makeFilterExcludes(patterns []string) Filterer {
return func(in <-chan string) <-chan string {
return filterExcludes(in, patterns)
}
}

// Filter files that match any of the glob patterns.
func filterExcludes(in <-chan string, patterns []string) <-chan string {
var globs []glob.Glob
Expand Down

0 comments on commit 8027144

Please sign in to comment.