-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathweb-link.rkt
77 lines (63 loc) · 2.34 KB
/
web-link.rkt
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#lang racket/base
(require racket/contract/base)
(provide
(contract-out
[web-link
(-> url-coercible? link-relation-coercible? url-coercible? web-link?)]
[web-link? (-> any/c boolean?)]
[web-link-source (-> web-link? url?)]
[web-link-relation (-> web-link? (or/c url? symbol?))]
[web-link-target (-> web-link? url?)]))
(require net/url
racket/struct
rebellion/type/tuple)
(module+ test
(require (submod "..")
racket/format
rackunit))
;@------------------------------------------------------------------------------
(define url-coercible? (or/c url? string?))
(define (url-coerce url-ish)
(if (string? url-ish) (string->url url-ish) url-ish))
(define link-relation-coercible? (or/c url? string? symbol?))
(define (link-relation-coerce relation-ish)
(if (string? relation-ish) (string->url relation-ish) relation-ish))
(define (link-relation->writable-value relation)
(if (symbol? relation) relation (url->string relation)))
(define (property-maker descriptor)
(define name (tuple-type-name (tuple-descriptor-type descriptor)))
(define accessor (tuple-descriptor-accessor descriptor))
(define equal+hash (default-tuple-equal+hash descriptor))
(define custom-write
(make-constructor-style-printer
(λ (_) name)
(λ (this) (list (url->string (accessor this 0))
(link-relation->writable-value (accessor this 1))
(url->string (accessor this 2))))))
(list (cons prop:equal+hash equal+hash)
(cons prop:custom-write custom-write)))
(define-tuple-type web-link (source relation target)
#:property-maker property-maker
#:omit-root-binding)
(define (web-link source relation target)
(constructor:web-link (url-coerce source)
(link-relation-coerce relation)
(url-coerce target)))
(module+ test
(test-case "prop:custom-write"
(define link (web-link "http://example.org" 'stylesheet "/styles.css"))
(check-equal? (~v link)
#<<END
(web-link "http://example.org" 'stylesheet "/styles.css")
END
)
(check-equal? (~s link)
#<<END
#<web-link: "http://example.org" stylesheet "/styles.css">
END
)
(check-equal? (~a link)
#<<END
#<web-link: http://example.org stylesheet /styles.css>
END
)))