diff options
Diffstat (limited to 'gnu/services')
| -rw-r--r-- | gnu/services/configuration.scm | 55 | ||||
| -rw-r--r-- | gnu/services/mail.scm | 2 |
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) |
