refactor: simplify module composition

This commit is contained in:
2026-04-22 02:35:26 +02:00
parent 3b6c42ebe3
commit 5eec5689f4
25 changed files with 615 additions and 448 deletions
+89 -74
View File
@@ -3,10 +3,41 @@ let
mkNullableOption =
type:
lib.mkOption {
inherit type;
type = lib.types.nullOr type;
default = null;
};
hasSinglePrimaryEmail =
user: builtins.length (lib.filter (email: email.primary) (builtins.attrValues user.emails)) == 1;
primaryEmailFallback = {
address = "";
primary = false;
type = "";
};
sourceControlScopeType = lib.types.enum [
"personal"
"work"
];
pointerAccelProfileType = lib.types.enum [
"adaptive"
"flat"
];
pointerScrollMethodType = lib.types.enum [
"no-scroll"
"two-finger"
"edge"
"on-button-down"
];
touchpadClickMethodType = lib.types.enum [
"button-areas"
"clickfinger"
];
emailType = lib.types.submodule (
{ ... }:
{
@@ -79,10 +110,7 @@ let
};
projectScope = lib.mkOption {
type = lib.types.enum [
"personal"
"work"
];
type = sourceControlScopeType;
default = "personal";
};
};
@@ -91,6 +119,10 @@ let
userType = lib.types.submodule (
{ config, ... }:
let
primaryEmails = lib.filter (email: email.primary) (builtins.attrValues config.emails);
primaryEmail = if primaryEmails == [ ] then primaryEmailFallback else builtins.head primaryEmails;
in
{
options = {
name = lib.mkOption {
@@ -118,11 +150,19 @@ let
type = lib.types.attrsOf emailType;
};
primaryEmail = lib.mkOption {
type = emailType;
readOnly = true;
description = "Derived primary email entry for this user.";
};
sourceControl = lib.mkOption {
type = sourceControlType;
default = { };
};
};
config.primaryEmail = primaryEmail;
}
);
@@ -179,28 +219,12 @@ let
{ ... }:
{
options = {
accelProfile = mkNullableOption (
lib.types.nullOr (
lib.types.enum [
"adaptive"
"flat"
]
)
);
accelSpeed = mkNullableOption (lib.types.nullOr lib.types.float);
leftHanded = mkNullableOption (lib.types.nullOr lib.types.bool);
middleEmulation = mkNullableOption (lib.types.nullOr lib.types.bool);
naturalScrolling = mkNullableOption (lib.types.nullOr lib.types.bool);
scrollMethod = mkNullableOption (
lib.types.nullOr (
lib.types.enum [
"no-scroll"
"two-finger"
"edge"
"on-button-down"
]
)
);
accelProfile = mkNullableOption (pointerAccelProfileType);
accelSpeed = mkNullableOption lib.types.float;
leftHanded = mkNullableOption lib.types.bool;
middleEmulation = mkNullableOption lib.types.bool;
naturalScrolling = mkNullableOption lib.types.bool;
scrollMethod = mkNullableOption pointerScrollMethodType;
};
}
);
@@ -209,38 +233,15 @@ let
{ ... }:
{
options = {
accelProfile = mkNullableOption (
lib.types.nullOr (
lib.types.enum [
"adaptive"
"flat"
]
)
);
accelSpeed = mkNullableOption (lib.types.nullOr lib.types.float);
clickMethod = mkNullableOption (
lib.types.nullOr (
lib.types.enum [
"button-areas"
"clickfinger"
]
)
);
disableWhileTyping = mkNullableOption (lib.types.nullOr lib.types.bool);
leftHanded = mkNullableOption (lib.types.nullOr lib.types.bool);
middleEmulation = mkNullableOption (lib.types.nullOr lib.types.bool);
naturalScrolling = mkNullableOption (lib.types.nullOr lib.types.bool);
scrollMethod = mkNullableOption (
lib.types.nullOr (
lib.types.enum [
"no-scroll"
"two-finger"
"edge"
"on-button-down"
]
)
);
tapping = mkNullableOption (lib.types.nullOr lib.types.bool);
accelProfile = mkNullableOption (pointerAccelProfileType);
accelSpeed = mkNullableOption lib.types.float;
clickMethod = mkNullableOption touchpadClickMethodType;
disableWhileTyping = mkNullableOption lib.types.bool;
leftHanded = mkNullableOption lib.types.bool;
middleEmulation = mkNullableOption lib.types.bool;
naturalScrolling = mkNullableOption lib.types.bool;
scrollMethod = mkNullableOption pointerScrollMethodType;
tapping = mkNullableOption lib.types.bool;
};
}
);
@@ -294,23 +295,37 @@ let
);
in
{
flake.modules.nixos.meta = {
options.meta.host = lib.mkOption {
type = hostType;
};
};
flake.modules.homeManager.meta = {
options.meta = {
host = lib.mkOption {
type = lib.types.nullOr hostType;
default = null;
flake.modules.nixos.meta =
{ config, ... }:
{
options.meta.host = lib.mkOption {
type = hostType;
};
user = lib.mkOption {
type = lib.types.nullOr userType;
default = null;
config.assertions = lib.mapAttrsToList (userName: user: {
assertion = hasSinglePrimaryEmail user;
message = "User `${userName}` must define exactly one primary email entry.";
}) config.meta.host.users;
};
flake.modules.homeManager.meta =
{ config, ... }:
{
options.meta = {
host = lib.mkOption {
type = lib.types.nullOr hostType;
default = null;
};
user = lib.mkOption {
type = lib.types.nullOr userType;
default = null;
};
};
config.assertions = lib.optional (config.meta.user != null) {
assertion = hasSinglePrimaryEmail config.meta.user;
message = "User `${config.meta.user.name}` must define exactly one primary email entry.";
};
};
};
}