Skip to content

Commit 9d2139f

Browse files
committed
Add generic method to set Decoder options
Not as elegant as functional options, but it allows for adding more options later without increasing the API surface.
1 parent 96c5da1 commit 9d2139f

File tree

5 files changed

+46
-14
lines changed

5 files changed

+46
-14
lines changed

decoder.go

+11-4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ import (
66
"runtime"
77
)
88

9+
// A ParseOption allows to customize the behaviour of decoders.
10+
type ParseOption int
11+
12+
// Options which can configure the decoders.
13+
const (
14+
Base ParseOption = iota // Base IRI to resolve relative IRIs against.
15+
)
16+
917
// TripleDecoder parses RDF documents (serializations of an RDF graph).
1018
//
1119
// For streaming parsing, use the Decode() method to decode a single Triple
@@ -19,10 +27,9 @@ type TripleDecoder interface {
1927
// triples, or an error.
2028
DecodeAll() ([]Triple, error)
2129

22-
// SetBase sets the base IRI which will be used for resolving relative IRIs.
23-
// For formats that doesn't allow relative IRIs (N-Triples), this is a no-op.
24-
// TODO strip #fragment in implementations? - check w3.org spec.
25-
SetBase(IRI)
30+
// SetOption sets a parsing option to the given value. Not all options
31+
// are supported by all decoders.
32+
SetOption(ParseOption, interface{}) error
2633
}
2734

2835
// NewTripleDecoder returns a new TripleDecoder capable of parsing triples

nt.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,13 @@ func (d *ntDecoder) DecodeAll() ([]Triple, error) {
9999
return ts, nil
100100
}
101101

102-
// SetBase does nothing, but is needed to implement the TripleDecoder interface.
103-
func (d *ntDecoder) SetBase(i IRI) {}
102+
// SetOption sets a ParseOption to the give value
103+
func (d *ntDecoder) SetOption(o ParseOption, v interface{}) error {
104+
switch o {
105+
default:
106+
return fmt.Errorf("N-Triples decoder doesn't support option: %v", o)
107+
}
108+
}
104109

105110
// Parsing functions:
106111

rdfxml.go

+13-3
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,19 @@ func newRDFXMLDecoder(r io.Reader) *rdfXMLDecoder {
7070
return &rdfXMLDecoder{dec: xml.NewDecoder(r), nextState: parseXMLTopElem}
7171
}
7272

73-
// SetBase sets the base IRI of the decoder, to be used resolving relative IRIs.
74-
func (d *rdfXMLDecoder) SetBase(i IRI) {
75-
d.ctx.Base = i.str
73+
// SetOption sets a ParseOption to the give value
74+
func (d *rdfXMLDecoder) SetOption(o ParseOption, v interface{}) error {
75+
switch o {
76+
case Base:
77+
iri, ok := v.(IRI)
78+
if !ok {
79+
return fmt.Errorf("ParseOption \"Base\" must be an IRI.")
80+
}
81+
d.ctx.Base = iri.str
82+
default:
83+
return fmt.Errorf("RDF/XML decoder doesn't support option: %v", o)
84+
}
85+
return nil
7686
}
7787

7888
// Decode parses a RDF/XML document, and returns the next available triple,

rdfxml_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
func TestRDFXMLExamples(t *testing.T) {
1010
for i, test := range rdfxmlExamples {
1111
dec := NewTripleDecoder(bytes.NewBufferString(test.rdfxml), FormatRDFXML)
12-
dec.SetBase(IRI{str: "http://www.w3.org/2013/RDFXMLTests/" + test.file})
12+
dec.SetOption(Base, IRI{str: "http://www.w3.org/2013/RDFXMLTests/" + test.file})
1313
ts, err := dec.DecodeAll()
1414
if err != nil {
1515
t.Fatalf("[%d] parseRDFXML(%s).Serialize(FormatNT) => %v, want %q", i, test.rdfxml, err, test.nt)
@@ -32,7 +32,7 @@ func TestRDFXMLExamples(t *testing.T) {
3232
func TestRDFXML(t *testing.T) {
3333
for i, test := range rdfxmlTestSuite {
3434
dec := NewTripleDecoder(bytes.NewBufferString(test.rdfxml), FormatRDFXML)
35-
dec.SetBase(IRI{str: "http://www.w3.org/2013/RDFXMLTests/" + test.file})
35+
dec.SetOption(Base, IRI{str: "http://www.w3.org/2013/RDFXMLTests/" + test.file})
3636
ts, err := dec.DecodeAll()
3737
if test.err == "TODO" {
3838
continue

ttl.go

+13-3
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,19 @@ func newTTLDecoder(r io.Reader) *ttlDecoder {
3737
}
3838
}
3939

40-
// SetBase sets the base IRI of the decoder, to be used resolving relative IRIs.
41-
func (d *ttlDecoder) SetBase(i IRI) {
42-
d.base = i
40+
// SetOption sets a ParseOption to the give value
41+
func (d *ttlDecoder) SetOption(o ParseOption, v interface{}) error {
42+
switch o {
43+
case Base:
44+
iri, ok := v.(IRI)
45+
if !ok {
46+
return fmt.Errorf("ParseOption \"Base\" must be an IRI.")
47+
}
48+
d.base = iri
49+
default:
50+
return fmt.Errorf("RDF/XML decoder doesn't support option: %v", o)
51+
}
52+
return nil
4353
}
4454

4555
// Decode parses a Turtle document, and returns the next valid triple, or an error.

0 commit comments

Comments
 (0)