···1+{ config, lib, pkgs, ... }:
2+3+with lib;
4+5+let
6+ cfg = config.hardware.sane.brscan5;
7+8+ netDeviceList = attrValues cfg.netDevices;
9+10+ etcFiles = pkgs.callPackage ./brscan5_etc_files.nix { netDevices = netDeviceList; };
11+12+ netDeviceOpts = { name, ... }: {
13+14+ options = {
15+16+ name = mkOption {
17+ type = types.str;
18+ description = ''
19+ The friendly name you give to the network device. If undefined,
20+ the name of attribute will be used.
21+ '';
22+23+ example = literalExample "office1";
24+ };
25+26+ model = mkOption {
27+ type = types.str;
28+ description = ''
29+ The model of the network device.
30+ '';
31+32+ example = literalExample "MFC-7860DW";
33+ };
34+35+ ip = mkOption {
36+ type = with types; nullOr str;
37+ default = null;
38+ description = ''
39+ The ip address of the device. If undefined, you will have to
40+ provide a nodename.
41+ '';
42+43+ example = literalExample "192.168.1.2";
44+ };
45+46+ nodename = mkOption {
47+ type = with types; nullOr str;
48+ default = null;
49+ description = ''
50+ The node name of the device. If undefined, you will have to
51+ provide an ip.
52+ '';
53+54+ example = literalExample "BRW0080927AFBCE";
55+ };
56+57+ };
58+59+60+ config =
61+ { name = mkDefault name;
62+ };
63+ };
64+65+in
66+67+{
68+ options = {
69+70+ hardware.sane.brscan5.enable =
71+ mkEnableOption "Brother's brscan5 scan backend" // {
72+ description = ''
73+ When enabled, will automatically register the "brscan5" sane
74+ backend and bring configuration files to their expected location.
75+ '';
76+ };
77+78+ hardware.sane.brscan5.netDevices = mkOption {
79+ default = {};
80+ example =
81+ { office1 = { model = "MFC-7860DW"; ip = "192.168.1.2"; };
82+ office2 = { model = "MFC-7860DW"; nodename = "BRW0080927AFBCE"; };
83+ };
84+ type = with types; attrsOf (submodule netDeviceOpts);
85+ description = ''
86+ The list of network devices that will be registered against the brscan5
87+ sane backend.
88+ '';
89+ };
90+ };
91+92+ config = mkIf (config.hardware.sane.enable && cfg.enable) {
93+94+ hardware.sane.extraBackends = [
95+ pkgs.brscan5
96+ ];
97+98+ environment.etc."opt/brother/scanner/brscan5" =
99+ { source = "${etcFiles}/etc/opt/brother/scanner/brscan5"; };
100+ environment.etc."opt/brother/scanner/models" =
101+ { source = "${etcFiles}/etc/opt/brother/scanner/brscan5/models"; };
102+ environment.etc."sane.d/dll.d/brother5.conf".source = "${pkgs.brscan5}/etc/sane.d/dll.d/brother.conf";
103+104+ assertions = [
105+ { assertion = all (x: !(null != x.ip && null != x.nodename)) netDeviceList;
106+ message = ''
107+ When describing a network device as part of the attribute list
108+ `hardware.sane.brscan5.netDevices`, only one of its `ip` or `nodename`
109+ attribute should be specified, not both!
110+ '';
111+ }
112+ ];
113+114+ };
115+}