summaryrefslogtreecommitdiff
path: root/gnu/services
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/services')
-rw-r--r--gnu/services/configuration.scm55
-rw-r--r--gnu/services/mail.scm2
2 files changed, 44 insertions, 13 deletions
diff --git a/gnu/services/configuration.scm b/gnu/services/configuration.scm
index f6b20fb82b0..c39ea5a02a0 100644
--- a/gnu/services/configuration.scm
+++ b/gnu/services/configuration.scm
@@ -27,7 +27,8 @@
27 #:use-module (guix records) 27 #:use-module (guix records)
28 #:use-module (guix gexp) 28 #:use-module (guix gexp)
29 #:use-module ((guix utils) #:select (source-properties->location)) 29 #:use-module ((guix utils) #:select (source-properties->location))
30 #:use-module ((guix diagnostics) #:select (formatted-message location-file)) 30 #:use-module ((guix diagnostics)
31 #:select (formatted-message location-file &error-location))
31 #:use-module ((guix modules) #:select (file-name->module-name)) 32 #:use-module ((guix modules) #:select (file-name->module-name))
32 #:use-module (guix i18n) 33 #:use-module (guix i18n)
33 #:autoload (texinfo) (texi-fragment->stexi) 34 #:autoload (texinfo) (texi-fragment->stexi)
@@ -87,9 +88,17 @@
87(define (configuration-error message) 88(define (configuration-error message)
88 (raise (condition (&message (message message)) 89 (raise (condition (&message (message message))
89 (&configuration-error)))) 90 (&configuration-error))))
90(define (configuration-field-error field val) 91(define (configuration-field-error loc field value)
91 (configuration-error 92 (raise (apply
92 (format #f "Invalid value for field ~a: ~s" field val))) 93 make-compound-condition
94 (formatted-message (G_ "invalid value ~s for field '~a'")
95 value field)
96 (condition (&configuration-error))
97 (if loc
98 (list (condition
99 (&error-location (location loc))))
100 '()))))
101
93(define (configuration-missing-field kind field) 102(define (configuration-missing-field kind field)
94 (configuration-error 103 (configuration-error
95 (format #f "~a configuration missing required field ~a" kind field))) 104 (format #f "~a configuration missing required field ~a" kind field)))
@@ -210,9 +219,33 @@ does not have a default value" field kind)))
210 (id #'stem #'serialize- type)))))) 219 (id #'stem #'serialize- type))))))
211 #'(field-type ...) 220 #'(field-type ...)
212 #'((custom-serializer ...) ...)))) 221 #'((custom-serializer ...) ...))))
222 (define (field-sanitizer name pred)
223 ;; Define a macro for use as a record field sanitizer, where NAME
224 ;; is the name of the field and PRED is the predicate that tells
225 ;; whether a value is valid for this field.
226 #`(define-syntax #,(id #'stem #'validate- #'stem #'- name)
227 (lambda (s)
228 ;; Make sure the given VALUE, for field NAME, passes PRED.
229 (syntax-case s ()
230 ((_ value)
231 (with-syntax ((name #'#,name)
232 (pred #'#,pred)
233 (loc (datum->syntax #'value
234 (syntax-source #'value))))
235 #'(if (pred value)
236 value
237 (configuration-field-error
238 (and=> 'loc source-properties->location)
239 'name value))))))))
240
213 #`(begin 241 #`(begin
242 ;; Define field validation macros.
243 #,@(map field-sanitizer
244 #'(field ...)
245 #'(field-predicate ...))
246
214 (define-record-type* #,(id #'stem #'< #'stem #'>) 247 (define-record-type* #,(id #'stem #'< #'stem #'>)
215 #,(id #'stem #'% #'stem) 248 stem
216 #,(id #'stem #'make- #'stem) 249 #,(id #'stem #'make- #'stem)
217 #,(id #'stem #'stem #'?) 250 #,(id #'stem #'stem #'?)
218 (%location #,(id #'stem #'stem #'-location) 251 (%location #,(id #'stem #'stem #'-location)
@@ -220,10 +253,13 @@ does not have a default value" field kind)))
220 source-properties->location)) 253 source-properties->location))
221 (innate)) 254 (innate))
222 #,@(map (lambda (name getter def) 255 #,@(map (lambda (name getter def)
223 #`(#,name #,getter (default #,def))) 256 #`(#,name #,getter (default #,def)
257 (sanitize
258 #,(id #'stem #'validate- #'stem #'- name))))
224 #'(field ...) 259 #'(field ...)
225 #'(field-getter ...) 260 #'(field-getter ...)
226 #'(field-default ...))) 261 #'(field-default ...)))
262
227 (define #,(id #'stem #'stem #'-fields) 263 (define #,(id #'stem #'stem #'-fields)
228 (list (configuration-field 264 (list (configuration-field
229 (name 'field) 265 (name 'field)
@@ -240,12 +276,7 @@ does not have a default value" field kind)))
240 '#,(id #'stem #'% #'stem) 'field) 276 '#,(id #'stem #'% #'stem) 'field)
241 field-default))) 277 field-default)))
242 (documentation doc)) 278 (documentation doc))
243 ...)) 279 ...))))))))
244 (define-syntax-rule (stem arg (... ...))
245 (let ((conf (#,(id #'stem #'% #'stem) arg (... ...))))
246 (validate-configuration conf
247 #,(id #'stem #'stem #'-fields))
248 conf))))))))
249 280
250(define no-serialization ;syntactic keyword for 'define-configuration' 281(define no-serialization ;syntactic keyword for 'define-configuration'
251 '(no serialization)) 282 '(no serialization))
diff --git a/gnu/services/mail.scm b/gnu/services/mail.scm
index d99743ac311..c2fd4d8670b 100644
--- a/gnu/services/mail.scm
+++ b/gnu/services/mail.scm
@@ -285,7 +285,7 @@ the section name.")
285 (serialize-fifo-listener-configuration field-name val)) 285 (serialize-fifo-listener-configuration field-name val))
286 ((inet-listener-configuration? val) 286 ((inet-listener-configuration? val)
287 (serialize-inet-listener-configuration field-name val)) 287 (serialize-inet-listener-configuration field-name val))
288 (else (configuration-field-error field-name val)))) 288 (else (configuration-field-error #f field-name val))))
289(define (listener-configuration-list? val) 289(define (listener-configuration-list? val)
290 (and (list? val) (and-map listener-configuration? val))) 290 (and (list? val) (and-map listener-configuration? val)))
291(define (serialize-listener-configuration-list field-name val) 291(define (serialize-listener-configuration-list field-name val)