From 1c803e63f9560b93afeec9f7342f4413ff3cec46 Mon Sep 17 00:00:00 2001 From: Maxim Cournoyer Date: Wed, 24 Aug 2022 14:40:38 +0200 Subject: services: configuration: Add a 'maybe-value-set?' procedure. * gnu/services/configuration.scm (maybe-value-set?): New procedure. * doc/guix.texi (Complex Configurations): Document it. Remove comment showing usage of 'maybe-string' with a default value, which doesn't make sense. Co-authored-by: Attila Lendvai --- gnu/services/configuration.scm | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'gnu/services/configuration.scm') diff --git a/gnu/services/configuration.scm b/gnu/services/configuration.scm index 3007e8de35..e2c4fe9998 100644 --- a/gnu/services/configuration.scm +++ b/gnu/services/configuration.scm @@ -57,6 +57,7 @@ serialize-configuration define-maybe define-maybe/no-serialization + maybe-value-set? generate-documentation configuration->documentation empty-serializer @@ -142,7 +143,8 @@ does not have a default value" field kind))) (id #'stem #'serialize-maybe- #'stem)))) #`(begin (define (maybe-stem? val) - (or (eq? val 'unset) (stem? val))) + (or (not (maybe-value-set? val)) + (stem? val))) #,@(if serialize? (list #'(define (serialize-maybe-stem field-name val) (if (stem? val) @@ -260,11 +262,10 @@ does not have a default value" field kind))) (default-value-thunk (lambda () (display '#,(id #'stem #'% #'stem)) - (if (eq? (syntax->datum field-default) - 'unset) + (if (maybe-value-set? (syntax->datum field-default)) + field-default (configuration-missing-default-value - '#,(id #'stem #'% #'stem) 'field) - field-default))) + '#,(id #'stem #'% #'stem) 'field)))) (documentation doc)) ...)))))))) @@ -300,6 +301,10 @@ does not have a default value" field kind))) (define (empty-serializer field-name val) "") (define serialize-package empty-serializer) +(define (maybe-value-set? value) + "Predicate to check whether a 'maybe' value was explicitly provided." + (not (eq? 'unset value))) + ;; A little helper to make it easier to document all those fields. (define (generate-documentation documentation documentation-name) (define (str x) (object->string x)) -- cgit v1.2.3 From 147f8f19f844b8acc602ddcb49b4a1c0b9226c4d Mon Sep 17 00:00:00 2001 From: Attila Lendvai Date: Wed, 24 Aug 2022 14:40:39 +0200 Subject: services: configuration: Add %unset-value exported variable. * gnu/services/configuration.scm (%unset-value): New variable. (normalize-field-type+def): Use it. (maybe-value-unset?): Use it. Signed-off-by: Maxim Cournoyer --- gnu/services/configuration.scm | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'gnu/services/configuration.scm') diff --git a/gnu/services/configuration.scm b/gnu/services/configuration.scm index e2c4fe9998..a9426066b9 100644 --- a/gnu/services/configuration.scm +++ b/gnu/services/configuration.scm @@ -57,6 +57,7 @@ serialize-configuration define-maybe define-maybe/no-serialization + %unset-value maybe-value-set? generate-documentation configuration->documentation @@ -172,10 +173,10 @@ does not have a default value" field kind))) (values #'(field-type def))) ((field-type) (identifier? #'field-type) - (values #'(field-type 'unset))) + (values #'(field-type %unset-value))) (field-type (identifier? #'field-type) - (values #'(field-type 'unset))))) + (values #'(field-type %unset-value))))) (define (define-configuration-helper serialize? serializer-prefix syn) (syntax-case syn () @@ -301,9 +302,18 @@ does not have a default value" field kind))) (define (empty-serializer field-name val) "") (define serialize-package empty-serializer) +;; Ideally this should be an implementation detail, but we export it +;; to provide a simpler API that enables unsetting a configuration +;; field that has a maybe type, but also a default value. +;; +;; An example use-case would be something like a network application +;; that uses a default port, but the field can explicitly be unset to +;; request a random port at startup. +(define %unset-value 'unset) + (define (maybe-value-set? value) "Predicate to check whether a 'maybe' value was explicitly provided." - (not (eq? 'unset value))) + (not (eq? %unset-value value))) ;; A little helper to make it easier to document all those fields. (define (generate-documentation documentation documentation-name) -- cgit v1.2.3 From cc32cd41f74c642583837b43444646d52b3fd5da Mon Sep 17 00:00:00 2001 From: Attila Lendvai Date: Wed, 24 Aug 2022 14:40:40 +0200 Subject: services: configuration: Add maybe-value exported procedure. * gnu/services/configuration.scm (maybe-value): New procedure. Signed-off-by: Maxim Cournoyer --- gnu/services/configuration.scm | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'gnu/services/configuration.scm') diff --git a/gnu/services/configuration.scm b/gnu/services/configuration.scm index a9426066b9..60965486a7 100644 --- a/gnu/services/configuration.scm +++ b/gnu/services/configuration.scm @@ -58,6 +58,7 @@ define-maybe define-maybe/no-serialization %unset-value + maybe-value maybe-value-set? generate-documentation configuration->documentation @@ -315,6 +316,15 @@ does not have a default value" field kind))) "Predicate to check whether a 'maybe' value was explicitly provided." (not (eq? %unset-value value))) +;; Ideally there should be a compiler macro for this predicate, that expands +;; to a conditional that only instantiates the default value when needed. +(define* (maybe-value value #:optional (default #f)) + "Returns VALUE, unless it is the unset value, in which case it returns +DEFAULT." + (if (maybe-value-set? value) + value + default)) + ;; A little helper to make it easier to document all those fields. (define (generate-documentation documentation documentation-name) (define (str x) (object->string x)) -- cgit v1.2.3 From 6fb9759ef3b8eb2a2b10c3f02a57ece29b5c53ba Mon Sep 17 00:00:00 2001 From: Attila Lendvai Date: Wed, 24 Aug 2022 14:40:42 +0200 Subject: services: configuration: Change the value of the unset marker. The new value of %unset-value sticks out more when something goes wrong, and is also more unique; i.e. easier to search for. Signed-off-by: Maxim Cournoyer --- gnu/services/configuration.scm | 5 +++-- gnu/services/messaging.scm | 2 +- tests/services/configuration.scm | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) (limited to 'gnu/services/configuration.scm') diff --git a/gnu/services/configuration.scm b/gnu/services/configuration.scm index 60965486a7..83da63c1b3 100644 --- a/gnu/services/configuration.scm +++ b/gnu/services/configuration.scm @@ -305,12 +305,13 @@ does not have a default value" field kind))) ;; Ideally this should be an implementation detail, but we export it ;; to provide a simpler API that enables unsetting a configuration -;; field that has a maybe type, but also a default value. +;; field that has a maybe type, but also a default value. We give it +;; a value that sticks out to the reader when something goes wrong. ;; ;; An example use-case would be something like a network application ;; that uses a default port, but the field can explicitly be unset to ;; request a random port at startup. -(define %unset-value 'unset) +(define %unset-value '%unset-marker%) (define (maybe-value-set? value) "Predicate to check whether a 'maybe' value was explicitly provided." diff --git a/gnu/services/messaging.scm b/gnu/services/messaging.scm index 59cb486778..02712ede7c 100644 --- a/gnu/services/messaging.scm +++ b/gnu/services/messaging.scm @@ -95,7 +95,7 @@ ;; doesn't interfere with ;; define-configuration and define-maybe ;; internals. - #''unset def)) + #''%unset-marker% def)) #'(def ...) #'(target ...))) ((new-doc ...) (map (lambda (doc target) diff --git a/tests/services/configuration.scm b/tests/services/configuration.scm index 8ed4ed4b66..4f8a74dc8a 100644 --- a/tests/services/configuration.scm +++ b/tests/services/configuration.scm @@ -150,7 +150,7 @@ (protocol maybe-symbol "")) ;;; Maybe symbol values are currently seen as serializable, because the -;;; unspecified value is 'unset, which is a symbol itself. +;;; unspecified value is '%unset-marker%, which is a symbol itself. ;;; TODO: Remove expected fail marker after resolution. (test-expect-fail 1) (test-equal "symbol maybe value serialization, unspecified" -- cgit v1.2.3