services: configuration: Support (field1 maybe-number "") format.

As opposed to explicitly using 'disabled as value, or using the
(field1 (maybe-number) "") format.

It's mostly the work of Maxime Devos shared under #54674, with some
modifications by Attila Lendvai.

* gnu/services/configuration.scm (normalize-field-type+def): New function.
(define-configuration-helper) (define-configuration): Support new field
format.
* tests/services/configuration.scm (config-with-maybe-number->string): New
function.
("maybe value serialization of the instance"): New test.
("maybe value serialization of the instance, unspecified"): New test.

Signed-off-by: Ludovic Courtès <ludo@gnu.org>
This commit is contained in:
Attila Lendvai 2022-05-17 13:39:26 +02:00 committed by Ludovic Courtès
parent 3d0749b4e3
commit e11517052b
No known key found for this signature in database
GPG key ID: 090B11993D9AEBB5
2 changed files with 114 additions and 83 deletions

View file

@ -5,6 +5,7 @@
;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz> ;;; Copyright © 2021 Xinglu Chen <public@yoctocell.xyz>
;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com> ;;; Copyright © 2021 Maxim Cournoyer <maxim.cournoyer@gmail.com>
;;; Copyright © 2021 Andrew Tropin <andrew@trop.in> ;;; Copyright © 2021 Andrew Tropin <andrew@trop.in>
;;; Copyright © 2022 Maxime Devos <maximedevos@telenet.be>
;;; ;;;
;;; This file is part of GNU Guix. ;;; This file is part of GNU Guix.
;;; ;;;
@ -162,10 +163,26 @@ (define-maybe-helper #t #f #'(_ stem))))))
(define-syntax-rule (define-maybe/no-serialization stem) (define-syntax-rule (define-maybe/no-serialization stem)
(define-maybe stem (no-serialization))) (define-maybe stem (no-serialization)))
(define (normalize-field-type+def s)
(syntax-case s ()
((field-type def)
(identifier? #'field-type)
(values #'(field-type def)))
((field-type)
(identifier? #'field-type)
(values #'(field-type 'disabled)))
(field-type
(identifier? #'field-type)
(values #'(field-type 'disabled)))))
(define (define-configuration-helper serialize? serializer-prefix syn) (define (define-configuration-helper serialize? serializer-prefix syn)
(syntax-case syn () (syntax-case syn ()
((_ stem (field (field-type def ...) doc custom-serializer ...) ...) ((_ stem (field field-type+def doc custom-serializer ...) ...)
(with-syntax (((field-getter ...) (with-syntax
((((field-type def) ...)
(map normalize-field-type+def #'(field-type+def ...))))
(with-syntax
(((field-getter ...)
(map (lambda (field) (map (lambda (field)
(id #'stem #'stem #'- field)) (id #'stem #'stem #'- field))
#'(field ...))) #'(field ...)))
@ -176,12 +193,8 @@ (define (define-configuration-helper serialize? serializer-prefix syn)
((field-default ...) ((field-default ...)
(map (match-lambda (map (match-lambda
((field-type default-value) ((field-type default-value)
default-value) default-value))
((field-type) #'((field-type def) ...)))
;; Quote `undefined' to prevent a possibly
;; unbound warning.
(syntax 'undefined)))
#'((field-type def ...) ...)))
((field-serializer ...) ((field-serializer ...)
(map (lambda (type custom-serializer) (map (lambda (type custom-serializer)
(and serialize? (and serialize?
@ -233,7 +246,7 @@ (define-syntax-rule (stem arg (... ...))
(let ((conf (#,(id #'stem #'% #'stem) arg (... ...)))) (let ((conf (#,(id #'stem #'% #'stem) arg (... ...))))
(validate-configuration conf (validate-configuration conf
#,(id #'stem #'stem #'-fields)) #,(id #'stem #'stem #'-fields))
conf))))))) conf))))))))
(define no-serialization ;syntactic keyword for 'define-configuration' (define no-serialization ;syntactic keyword for 'define-configuration'
'(no serialization)) '(no serialization))
@ -241,26 +254,26 @@ (define no-serialization ;syntactic keyword for 'define-configuration'
(define-syntax define-configuration (define-syntax define-configuration
(lambda (s) (lambda (s)
(syntax-case s (no-serialization prefix) (syntax-case s (no-serialization prefix)
((_ stem (field (field-type def ...) doc custom-serializer ...) ... ((_ stem (field field-type+def doc custom-serializer ...) ...
(no-serialization)) (no-serialization))
(define-configuration-helper (define-configuration-helper
#f #f #'(_ stem (field (field-type def ...) doc custom-serializer ...) #f #f #'(_ stem (field field-type+def doc custom-serializer ...)
...))) ...)))
((_ stem (field (field-type def ...) doc custom-serializer ...) ... ((_ stem (field field-type+def doc custom-serializer ...) ...
(prefix serializer-prefix)) (prefix serializer-prefix))
(define-configuration-helper (define-configuration-helper
#t #'serializer-prefix #'(_ stem (field (field-type def ...) #t #'serializer-prefix #'(_ stem (field field-type+def
doc custom-serializer ...) doc custom-serializer ...)
...))) ...)))
((_ stem (field (field-type def ...) doc custom-serializer ...) ...) ((_ stem (field field-type+def doc custom-serializer ...) ...)
(define-configuration-helper (define-configuration-helper
#t #f #'(_ stem (field (field-type def ...) doc custom-serializer ...) #t #f #'(_ stem (field field-type+def doc custom-serializer ...)
...)))))) ...))))))
(define-syntax-rule (define-configuration/no-serialization (define-syntax-rule (define-configuration/no-serialization
stem (field (field-type def ...) stem (field field-type+def
doc custom-serializer ...) ...) doc custom-serializer ...) ...)
(define-configuration stem (field (field-type def ...) (define-configuration stem (field field-type+def
doc custom-serializer ...) ... doc custom-serializer ...) ...
(no-serialization))) (no-serialization)))

View file

@ -27,6 +27,9 @@ (define-module (tests services configuration)
(test-begin "services-configuration") (test-begin "services-configuration")
(define (serialize-number field value)
(format #f "~a=~a" field value))
;;; ;;;
;;; define-configuration macro. ;;; define-configuration macro.
@ -47,7 +50,6 @@ (define-configuration port-configuration-cs
80 80
(port-configuration-cs-port (port-configuration-cs))) (port-configuration-cs-port (port-configuration-cs)))
(define serialize-number "")
(define-configuration port-configuration-ndv (define-configuration port-configuration-ndv
(port (number) "The port number.")) (port (number) "The port number."))
@ -101,15 +103,31 @@ (define-configuration configuration-with-prefix
(define-maybe number) (define-maybe number)
(define-configuration config-with-maybe-number (define-configuration config-with-maybe-number
(port (maybe-number 80) "The port number.")) (port (maybe-number 80) "")
(count maybe-number ""))
(define (serialize-number field value)
(format #f "~a=~a" field value))
(test-equal "maybe value serialization" (test-equal "maybe value serialization"
"port=80" "port=80"
(serialize-maybe-number "port" 80)) (serialize-maybe-number "port" 80))
(define (config-with-maybe-number->string x)
(eval (gexp->approximate-sexp
(serialize-configuration x config-with-maybe-number-fields))
(current-module)))
(test-equal "maybe value serialization of the instance"
"port=42count=43"
(config-with-maybe-number->string
(config-with-maybe-number
(port 42)
(count 43))))
(test-equal "maybe value serialization of the instance, unspecified"
"port=42"
(config-with-maybe-number->string
(config-with-maybe-number
(port 42))))
(define-maybe/no-serialization string) (define-maybe/no-serialization string)
(define-configuration config-with-maybe-string/no-serialization (define-configuration config-with-maybe-string/no-serialization