diff options
Diffstat (limited to 'gnu/services.scm')
-rw-r--r-- | gnu/services.scm | 62 |
1 files changed, 57 insertions, 5 deletions
diff --git a/gnu/services.scm b/gnu/services.scm index af4cffe819..b1b53fd18b 100644 --- a/gnu/services.scm +++ b/gnu/services.scm @@ -25,6 +25,7 @@ #:use-module (guix profiles) #:use-module (guix sets) #:use-module (guix ui) + #:use-module ((guix utils) #:select (source-properties->location)) #:use-module (guix modules) #:use-module (gnu packages base) #:use-module (gnu packages bash) @@ -47,6 +48,7 @@ service-type-extensions service-type-compose service-type-extend + service-type-default-value service service? @@ -60,6 +62,9 @@ fold-services service-error? + missing-value-service-error? + missing-value-service-error-type + missing-value-service-error-location missing-target-service-error? missing-target-service-error-service missing-target-service-error-target-type @@ -119,6 +124,10 @@ (target service-extension-target) ;<service-type> (compute service-extension-compute)) ;params -> params +(define &no-default-value + ;; Value used to denote service types that have no associated default value. + '(no default value)) + (define-record-type* <service-type> service-type make-service-type service-type? (name service-type-name) ;symbol (for debugging) @@ -132,7 +141,11 @@ ;; Extend the services' own parameters with the extension composition. (extend service-type-extend ;list of Any -> parameters - (default #f))) + (default #f)) + + ;; Optional default value for instances of this type. + (default-value service-type-default-value ;Any + (default &no-default-value))) (define (write-service-type type port) (format port "#<service-type ~a ~a>" @@ -143,11 +156,53 @@ ;; Services of a given type. (define-record-type <service> - (service type value) + (make-service type value) service? (type service-kind) (value service-value)) +(define-syntax service + (syntax-rules () + "Return a service instance of TYPE. The service value is VALUE or, if +omitted, TYPE's default value." + ((_ type value) + (make-service type value)) + ((_ type) + (%service-with-default-value (current-source-location) + type)))) + +(define (%service-with-default-value location type) + "Return a instance of service type TYPE with its default value, if any. If +TYPE does not have a default value, an error is raised." + ;; TODO: Currently this is a run-time error but with a little bit macrology + ;; we could turn it into an expansion-time error. + (let ((default (service-type-default-value type))) + (if (eq? default &no-default-value) + (let ((location (source-properties->location location))) + (raise + (condition + (&missing-value-service-error (type type) (location location)) + (&message + (message (format #f (_ "~a: no value specified \ +for service of type '~a'") + (location->string location) + (service-type-name type))))))) + (service type default)))) + +(define-condition-type &service-error &error + service-error?) + +(define-condition-type &missing-value-service-error &service-error + missing-value-service-error? + (type missing-value-service-error-type) + (location missing-value-service-error-location)) + + + +;;; +;;; Helpers. +;;; + (define service-parameters ;; Deprecated alias. service-value) @@ -541,9 +596,6 @@ kernel." ;;; Service folding. ;;; -(define-condition-type &service-error &error - service-error?) - (define-condition-type &missing-target-service-error &service-error missing-target-service-error? (service missing-target-service-error-service) |