Host interop for clojure.data.json: readers, numbers, dates, exceptions
Shaking out clojure.data.json's own test suite (now 134/137): - Reader.read(char[],off,len) bulk read + PushbackReader.unread(char[],off,len) on the string/pushback reader jhosts; instance? java.io.PushbackReader/ Reader/StringReader (data.json re-wraps a reader unless it's already a PushbackReader, so this is load-bearing for repeated reads). - number protocol dispatch by actual type: a flonum is Double (not Long), exact ratio is Ratio, exact integer is Long — value-host-tags split. - Integer/toHexString|toOctalString|toBinaryString|toString; .isNaN/.isInfinite as instance methods on numbers. - EOFException ctor/class; .isArray on a class-name string. - dispatch tags for the uuid/bigdec/inst host values so a protocol extended to java.util.UUID / java.math.BigDecimal / java.util.Date / java.time.Instant reaches its impl; canonical-host-tag strips java.math./java.time. - instant/zoned/local time values compare = by epoch-ms (two parsed Instants). - java.time.Instant/parse, java.sql.Date ctor + valueOf, TimeZone/getDefault, DateTimeFormatter/ISO_INSTANT. All runtime .ss (no re-mint). 9 corpus rows certified vs JVM; make test + shakesmoke green, 0 new divergences.
This commit is contained in:
parent
18874ce4ab
commit
31c8f56784
7 changed files with 112 additions and 19 deletions
|
|
@ -243,6 +243,15 @@
|
|||
|
||||
(register-hash-arm! jinst? (lambda (x) (jolt-hash (jinst-ms x))))
|
||||
|
||||
;; java.time.Instant/ZonedDateTime/LocalDateTime values (mk-instant/mk-zoned/mk-local
|
||||
;; jhosts) are equal when same kind + same epoch-ms — two parsed Instants compare =.
|
||||
(define (time-jhost? x) (and (jhost? x) (member (jhost-tag x) '("instant" "zoned-dt" "local-dt")) #t))
|
||||
(register-eq-arm! (lambda (a b) (or (time-jhost? a) (time-jhost? b)))
|
||||
(lambda (a b) (and (time-jhost? a) (time-jhost? b)
|
||||
(string=? (jhost-tag a) (jhost-tag b))
|
||||
(= (ms-of a) (ms-of b)))))
|
||||
(register-hash-arm! time-jhost? (lambda (x) (jolt-hash (ms-of x))))
|
||||
|
||||
(define (inst-pr i) (string-append "#inst \"" (inst-rfc3339 i) "\""))
|
||||
(register-pr-arm! jinst? inst-pr)
|
||||
(register-str-render! jinst? inst-rfc3339)
|
||||
|
|
@ -327,7 +336,10 @@
|
|||
(cons "ofLocalizedDateTime" (lambda (fs) (style-fmt 'datetime fs)))))
|
||||
(register-class-statics! "Instant"
|
||||
(list (cons "ofEpochMilli" (lambda (ms) (mk-instant (ms->exact ms))))
|
||||
(cons "now" (lambda () (mk-instant (now-ms))))))
|
||||
(cons "now" (lambda () (mk-instant (now-ms))))
|
||||
;; Instant/parse an ISO-8601 instant ("…T…Z") -> an instant value.
|
||||
(cons "parse" (lambda (s) (mk-instant (jinst-ms (jolt-inst-from-string
|
||||
(if (string? s) s (jolt-str-render-one s)))))))))
|
||||
(register-class-statics! "ZoneId"
|
||||
(list (cons "systemDefault" (lambda () (make-jhost "zone-id" (vector "system"))))
|
||||
(cons "of" (lambda (id) (make-jhost "zone-id" (vector id))))))
|
||||
|
|
@ -352,6 +364,13 @@
|
|||
(register-class-ctor! "java.util.Date" date-ctor)
|
||||
(register-class-ctor! "Timestamp" date-ctor)
|
||||
(register-class-ctor! "java.sql.Timestamp" date-ctor)
|
||||
;; java.sql.Date: (Date. year-1900 month0 day) builds UTC midnight of that civil
|
||||
;; date; valueOf parses "yyyy-MM-dd" to the same instant (so the two agree).
|
||||
(define (sql-date-midnight y mo d) (make-jinst (* 1000 (* (days-from-civil y mo d) 86400))))
|
||||
(register-class-ctor! "java.sql.Date"
|
||||
(lambda (y m d) (sql-date-midnight (+ 1900 (jnum->exact y)) (+ 1 (jnum->exact m)) (jnum->exact d))))
|
||||
(register-class-statics! "java.sql.Date"
|
||||
(list (cons "valueOf" (lambda (s) (parse-ms "yyyy-MM-dd" (if (string? s) s (jolt-str-render-one s)))))))
|
||||
|
||||
;; java.util.TimeZone: an opaque id holder (format-ms is UTC, so a non-UTC zone is
|
||||
;; not honored — only the UTC case the corpus uses is exercised).
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue