49 lines
1.6 KiB
Racket
49 lines
1.6 KiB
Racket
#lang racket/base
|
|
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; Canonical concept identity helpers.
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
(require racket/string
|
|
uuid)
|
|
|
|
(provide concept-id?
|
|
normalize-concept-id
|
|
new-concept-id
|
|
normalized-or-new-concept-id)
|
|
|
|
(define prefixed-uuid-concept-id-pattern
|
|
#px"(?i:^concept-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$)")
|
|
|
|
;; Concept ids are stored as plain UUID strings. Validation accepts uppercase
|
|
;; input, while normalization always produces the canonical lowercase form.
|
|
(define (concept-id? value)
|
|
(uuid-string? value))
|
|
|
|
(define (normalize-concept-id value)
|
|
(cond
|
|
[(uuid-string? value) (string-downcase value)]
|
|
[(and (string? value)
|
|
(regexp-match prefixed-uuid-concept-id-pattern value))
|
|
=> (lambda (match) (string-downcase (cadr match)))]
|
|
[else #f]))
|
|
|
|
(define (new-concept-id)
|
|
(uuid-string))
|
|
|
|
(define (normalized-or-new-concept-id value)
|
|
(or (normalize-concept-id value)
|
|
(new-concept-id)))
|
|
|
|
(module+ test
|
|
(require rackunit)
|
|
|
|
(define sample "a3c4f0d1-22e5-4c42-9a40-cc864993f785")
|
|
(check-true (concept-id? sample))
|
|
(check-true (concept-id? (string-upcase sample)))
|
|
(check-false (concept-id? (string-append "concept-" sample)))
|
|
(check-equal? (normalize-concept-id (string-upcase sample)) sample)
|
|
(check-equal? (normalize-concept-id (string-append "concept-" sample)) sample)
|
|
(check-false (normalize-concept-id "legacy:a:concept-1"))
|
|
(check-true (concept-id? (new-concept-id))))
|