about summary refs log tree commit diff
path: root/nix/modules/libvirtnix/xml.nix
blob: 10eefa396e5ba81f8305fb5e92e219c27f848d9e (plain)
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
{ lib, ... }:

# takes a few args and creats a valid xml tag pair out of it
#
# testTag = mkTag {
#   name = "name";
#   args = [
#     {
#       key = "arg1";
#       val = "arg1val";
#     }
#     {
#       key = "arg2";
#       val = "arg2val";
#     }
#   ];
#   value = "qwe";
#   children = [
#     (mkTag { name = "nested"; args = []; value = "qwe"; children = [];})
#   ];
# };
#
# <name arg1=arg1val arg2=arg2val>
#   value
#   {children}
# </name>
{
  name, # name of the tag to be used, such as `secret`, `description`, ...
  args ? [ ], # args, [ { key="a"; val="b"; } { key="c"; val="d"; } ]
  value ? "", # the value to place in the middle
  children ? [ ], # the child elements
  closing ? true, # add a closing tag
}:
let

  # filter out all values missing a key
  # this allows passing empty args such as `{}` which then get discarded
  filteredArgs = (builtins.filter (x: x ? key) args);

  # convert the list of attr sets into a list of strings
  mappedArgs = (map (x: "${x.key}='${x.val}'") filteredArgs);

  # [ "A" "B" "C" ] => [ "A" " " "B" " " "C" ]
  spacedArgs = lib.strings.intersperse "" mappedArgs;

  # [ "A" " " "B" " " "C" ] => "A B C"
  joinedArgs = lib.strings.concatStrings spacedArgs;

  # prefix the args with a space when inserting
  args_str = lib.optionalString (filteredArgs != [ ]) (" " + joinedArgs);

  child_evaled = lib.strings.concatStrings children;

  cond = condition: value: if condition then value else "";

  closingTag = if closing == true then "</${name}>" else "";
in
"<${name}${args_str}${cond (closing == false) "/"}>${value}${child_evaled}${lib.optionalString (closing) closingTag}"