unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
blob 88d145bc5011b24a27950942e2f41025adc8eea3 4557 bytes (raw)
name: gnu/services/configuration/generic-ini.scm 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
 
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2023 Bruno Victal <mirai@makinata.eu>
;;;
;;; This file is part of GNU Guix.
;;;
;;; GNU Guix is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; GNU Guix is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.

(define-module (gnu services configuration generic-ini)
  #:use-module (gnu services configuration)
  #:use-module (guix gexp)
  #:use-module (srfi srfi-171)
  #:use-module (ice-9 match)
  #:export (ini-entry?
            list-of-ini-entries?

            serialize-ini-configuration))

;;;
;;; Generic INI serializer
;;;

\f
;;;
;;; Predicates
;;;

;; This is the same format used in SRFI-233 but without comment support.
(define ini-entry?
  (match-lambda
    (((? symbol?) (? symbol?) (? string?)) #t)
    (_ #f)))

(define list-of-ini-entries?
  (list-of ini-entry?))

;;
;; Overall design document
;;
;; This module implements a generic INI serializer for a record-type defined
;; using define-configuration.
;; It expects that the serialize-<type> procedures return a list with
;; three elements of the form:
;;    (list section key value)
;; Where ‘section’ and ‘key’ are symbols and ‘value’ is a string.
;; The fields within define-configuration do not have to be ordered in,
;; any way whatsoever as the ‘serialize-ini’ will group them up automatically.
;; This implies that no assumptions should be made regarding the order of the
;; values in the serializied INI output.
;;
;; Additional notes:
;; Q: Why not replace rcons with string-append and forego the ungexp-splice?
;; A: The transduction happens outside of the G-Exp while the final string-append
;;    takes place in the G-Exp.
;;
;; Debugging tips: Open a REPL and try one transducer at a time from
;; ‘ini-transducer’.
;;

(define (add-section-header partition)
  (let ((header (caar partition)))
    (cons (list header)
          partition)))

(define serializer
  (match-lambda
    ((section)
     #~(format #f "[~a]~%" '#$section))
    ((section key value)
     #~(format #f "~a=~a~%" '#$key #$value))
    ;; Used for the newline between sections.
    ('*section-separator* "\n")))

(define ini-transducer
  (compose (tpartition car)
           (tmap add-section-header)
           (tadd-between '(*section-separator*))
           tconcatenate
           (tmap serializer)))

;; A “first-pass” serialization is performed and sorted in order
;; to group up the fields by “section” before passing through the
;; transducer.
(define (serialize-ini-configuration config fields)
  (let* ((srfi-233-IR
          ;; First pass: “serialize” into a (disordered) list of
          ;; SRFI-233 entries.
          (list-transduce (base-transducer config) rcons fields))
         (comparator (lambda (x y)
                       ;; Sort the SRFI-233 entries by section.
                       (string<=? (symbol->string (car x))
                                  (symbol->string (car y)))))
         (sorted-entries (sort srfi-233-IR comparator)))
    #~(string-append
       #$@(list-transduce ini-transducer rcons sorted-entries))))

;; FIXME:RFC:
;;       generic-ini- prefixed serializing procs?
;;       (perhaps prefixed as generic-ini: ?)
;; Example procedures:
;;
(define* (generic-ini-serialize-string field-name value #:key section)
  (list section field-name value))

;; field-name-transform can be used to “uglify” a field-name,
;; e.g. want-ipv6?  ->  want_ipv6
(define* (generic-ini-serialize-boolean field-name value #:key section
                            (field-name-transform identity))
  (list section (field-name-transform field-name)
        (if value "true" "false")))


;;; FIXME: delete this before inclusion, these are notes for the first RFC.
;;;
;;; Left out for now (but readily extendable):
;;;  * Custom leading (presumed to be whitespace) characters for entries
;;;    à la gitconfig, mostly pretty-printing purposes
;;;  * Configurable delimiter (\n, \r\n, \0, ...)
;;;  * Configurable Key-value separator (this is usually =)

debug log:

solving 88d145bc50 ...
found 88d145bc50 in https://yhetil.org/guix-patches/59632edef13e9ed3f922e67142a6288e995c5bef.1686427611.git.mirai@makinata.eu/

applying [1/1] https://yhetil.org/guix-patches/59632edef13e9ed3f922e67142a6288e995c5bef.1686427611.git.mirai@makinata.eu/
diff --git a/gnu/services/configuration/generic-ini.scm b/gnu/services/configuration/generic-ini.scm
new file mode 100644
index 0000000000..88d145bc50

Checking patch gnu/services/configuration/generic-ini.scm...
Applied patch gnu/services/configuration/generic-ini.scm cleanly.

index at:
100644 88d145bc5011b24a27950942e2f41025adc8eea3	gnu/services/configuration/generic-ini.scm

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).