// Form validators. Screens reference these rather than writing closures // inline, so an error message reads the same wherever the rule applies. String? requiredField(String? value) => (value == null || value.trim().isEmpty) ? 'Required' : null; String? validPort(String? value) { if (value == null || value.trim().isEmpty) return null; // falls back to 22 final port = int.tryParse(value.trim()); if (port == null) return 'Numbers only'; if (port < 1 || port > 65535) return 'Must be 1–65535'; return null; } String? validHost(String? value) { if (value == null || value.trim().isEmpty) return 'Required'; if (value.trim().contains(' ')) return 'No spaces allowed'; return null; } /// An absolute POSIX path, as every remote target must be. String? validRemotePath(String? value) { if (value == null || value.trim().isEmpty) return 'Required'; if (!value.trim().startsWith('/')) return 'Must start with /'; return null; }