services: configuration: Use transducers within serialize-configuration.

Introduces 'base-transducer', a SRFI-171 based transducer that can be used as a
starting point for writing custom configuration record serializing procedures.

This also fixes the symbol maybe-value serialization test case.

* gnu/services/configuration.scm (empty-serializer?): New predicate.
(base-transducer, tfilter-maybe-value): New procedure.
(serialize-configuration): Adapt to use base-transducer.

* gnu/services/telephony.scm (jami-account->alist): Use transducers to skip
fields that are unserializable or whose field maybe-value is unset.

* tests/services/configuration.scm: Remove test-expect-fail.

Signed-off-by: Maxim Cournoyer <maxim.cournoyer@gmail.com>
This commit is contained in:
Bruno Victal 2023-10-07 16:57:15 +01:00 committed by Maxim Cournoyer
parent 1b29e5db8f
commit a7994ed58d
No known key found for this signature in database
GPG key ID: 1260E46482E63562
3 changed files with 47 additions and 24 deletions

View file

@ -42,6 +42,7 @@ (define-module (gnu services configuration)
#:use-module (srfi srfi-26)
#:use-module (srfi srfi-34)
#:use-module (srfi srfi-35)
#:use-module (srfi srfi-171)
#:export (configuration-field
configuration-field-name
configuration-field-type
@ -59,6 +60,10 @@ (define-module (gnu services configuration)
define-configuration/no-serialization
no-serialization
empty-serializer?
tfilter-maybe-value
base-transducer
serialize-configuration
define-maybe
define-maybe/no-serialization
@ -125,13 +130,36 @@ (define-record-type* <configuration-field>
(default-value-thunk configuration-field-default-value-thunk)
(documentation configuration-field-documentation))
(define (serialize-configuration config fields)
#~(string-append
#$@(map (lambda (field)
(define (empty-serializer? field)
"Predicate that checks whether FIELD is exempt from serialization."
(eq? empty-serializer
(configuration-field-serializer field)))
(define (tfilter-maybe-value config)
"Return a transducer for CONFIG that removes all maybe-type fields whose
value is '%unset-marker."
(tfilter (lambda (field)
(let ((field-value ((configuration-field-getter field) config)))
(maybe-value-set? field-value)))))
(define (base-transducer config)
"Return a transducer for CONFIG that calls the serializing procedures only
for fields marked for serialization and whose values are not '%unset-marker."
(compose (tremove empty-serializer?)
;; Only serialize fields whose value isn't '%unset-marker%.
(tfilter-maybe-value config)
(tmap (lambda (field)
((configuration-field-serializer field)
(configuration-field-name field)
((configuration-field-getter field) config)))
fields)))
((configuration-field-getter field) config))))))
(define (serialize-configuration config fields)
"Return a G-expression that contains the values corresponding to the
FIELDS of CONFIG, a record that has been generated by `define-configuration'.
The G-expression can then be serialized to disk by using something like
`mixed-text-file'."
#~(string-append
#$@(list-transduce (base-transducer config) rcons fields)))
(define-syntax-rule (id ctx parts ...)
"Assemble PARTS into a raw (unhygienic) identifier."

View file

@ -37,6 +37,7 @@ (define-module (gnu services telephony)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-2)
#:use-module (srfi srfi-26)
#:use-module (srfi srfi-171)
#:use-module (ice-9 format)
#:use-module (ice-9 match)
#:export (jami-account
@ -204,22 +205,20 @@ (define (field-name->account-detail name)
('rendezvous-point? "Account.rendezVous")
('peer-discovery? "Account.peerDiscovery")
('bootstrap-hostnames "Account.hostname")
('name-server-uri "RingNS.uri")
(_ #f)))
('name-server-uri "RingNS.uri")))
(filter-map (lambda (field)
(and-let* ((name (field-name->account-detail
(define jami-account-transducer
(compose (tremove empty-serializer?)
(tfilter-maybe-value jami-account-object)
(tmap (lambda (field)
(let* ((name (field-name->account-detail
(configuration-field-name field)))
(value ((configuration-field-serializer field)
name ((configuration-field-getter field)
jami-account-object)))
;; The define-maybe default serializer produces an
;; empty string for unspecified values.
(value* (if (string-null? value)
#f
value)))
(cons name value*)))
jami-account-fields))
jami-account-object))))
(cons name value))))))
(list-transduce jami-account-transducer rcons jami-account-fields))
(define (jami-account-list? val)
(and (list? val)

View file

@ -337,13 +337,9 @@ (define-maybe symbol)
(define-configuration config-with-maybe-symbol
(protocol maybe-symbol ""))
;;; Maybe symbol values are currently seen as serializable, because the
;;; 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"
""
(gexp->approximate-sexp
(eval-gexp
(serialize-configuration (config-with-maybe-symbol)
config-with-maybe-symbol-fields)))