-
Notifications
You must be signed in to change notification settings - Fork 12
/
client.go
53 lines (42 loc) · 1.45 KB
/
client.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package ashash
import (
"strings"
"github.com/benpate/derp"
"github.com/benpate/hannibal/streams"
)
// Client is a streams.Client wrapper that searches for hash values in a document.
type Client struct {
innerClient streams.Client
}
// New creates a fully initialized Client object
func New(innerClient streams.Client) Client {
return Client{
innerClient: innerClient,
}
}
// Load retrieves a document from the underlying innerClient, then searches for hash values
// inside it (if required)
func (client Client) Load(url string, options ...any) (streams.Document, error) {
// Try to find a hash in the URL
baseURL, hash, found := strings.Cut(url, "#")
// If there is no hash, then proceed as is.
if !found {
return client.innerClient.Load(url, options...)
}
// Otherwise, try to load the baseURL and find the hash inside that document
result, err := client.innerClient.Load(baseURL, options)
if err != nil {
return result, err
}
// Search all properties at the top level of the document (not recursive)
// and scan through arrays (if present) looking for an ID that matches the original URL (base + hash)
for _, key := range result.MapKeys() {
for property := result.Get(key); property.NotNil(); property = property.Tail() {
if property.ID() == url {
return property, nil
}
}
}
// Not found.
return streams.NilDocument(), derp.NewNotFoundError("ashash.Client.Load", "Hash value not found in document", baseURL, hash, result.Value())
}