97jaz / gregor

Date and time library for Racket
45 stars 10 forks source link

Destructuring moment #24

Closed lyterk closed 7 years ago

lyterk commented 7 years ago

Hey, hobbyist Racket user here.

In a mailing list, you gave this code for destructuring sql-timestamp to convert to a moment: (define (sql-timestamp->moment t) (match-define (sql-timestamp y mo d h mi s n tz) t) (moment y mo d h mi s n #:tz (or tz 0)))

I was trying the converse operation with moment->sql-timestamp, but I could not get moment to destructure. Racket just throws a syntax error:

> (match-define (moment a b c d e f) no) ; stdin::1368: match: syntax error in pattern ; in: (moment a b c d e f)

I tried this with different patterns, wrapping the arguments in lists, but nothing took. I'm just using this function for now:

(define (moment->sql-timestamp mom) (let ([dat (->date mom)]) (match-let ([(list y mo d h mi s na tz) (list (->year dat) (->month dat) (->day dat) (->hours mom) (->minutes mom) (->seconds mom) (->nanoseconds mom) (->utc-offset mom))]) (sql-timestamp y mo d h mi s na tz))))

Kinda unrelated, but have you considered including moment->sql-timestamp in subsequent versions?

97jaz commented 7 years ago

It looks like I was confusing Gregor's features with those of a successor library that I've been (very) slowly working on. You're right: Gregor's structs don't have match-expanders.

You can define a match-expander yourself, if you want, though you can't use the name moment for it. (Or, rather, I'm sure you could if you went to a lot of trouble, but that's probably not worth it.) Try:

(require racket/match
         db)
(require gregor)

(define-match-expander moment*
  (syntax-rules ()
    [(_ y mo d h mi s n offset)
     (and (app ->year y)
          (app ->month mo)
          (app ->day d)
          (app ->hours h)
          (app ->minutes mi)
          (app ->seconds s)
          (app ->nanoseconds n)
          (app ->utc-offset offset))]))

(define (moment->sql-timestamp m)
  (match m
    [(moment* y mo d h mi s n offset)
     (sql-timestamp y mo d h mi s n offset)]))

And thank you for reminding me to add this feature to the new version.

lyterk commented 7 years ago

Awesome, that's just the answer I was looking for. Thanks for the quick reply.