Coverage for src/lexigram/admin/schema/boolean.py: 20%
46 statements
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 23:31 +0800
« prev ^ index » next coverage.py v7.15.4, created at 2026-08-24 23:31 +0800
1from __future__ import annotations
3from dataclasses import dataclass
4from typing import Any
6from lexigram.admin.schema.base import SchemaField
7from lexigram.admin.schema.exceptions import FieldError
8from lexigram.result import Err, Ok, Result
9from lexigram.ui import Element, Switch
12@dataclass(frozen=True, kw_only=True)
13class BooleanField(SchemaField[bool]):
14 """A boolean toggle field rendered as a Switch."""
16 def render_infolist_entry(self, value: Any) -> Any:
17 from lexigram.ui import InfolistEntry, InfolistEntryType
19 return InfolistEntry(
20 name=self.name,
21 label=self.label or self.name.replace("_", " ").title(),
22 value=value,
23 type=InfolistEntryType.BOOLEAN,
24 )
26 def render_form(
27 self, value: bool | None, *, errors: list[str] | None = None
28 ) -> Element:
29 kwargs: dict[str, Any] = {
30 "name": self.name,
31 "value": value if value is not None else False,
32 }
33 if self.label is not None:
34 kwargs["label"] = self.label
35 else:
36 kwargs["label"] = ""
37 if errors:
38 kwargs["error"] = errors[0]
39 if self.readonly:
40 kwargs["disabled"] = True
41 return Switch(**kwargs).render()
43 def render_column(self, record: Any, value: bool | None) -> Element:
44 if value is None:
45 return Element("span", "\u2014", class_="text-muted")
46 if value:
47 return Element("span", "\u2713", class_="text-success")
48 return Element("span", "\u2717", class_="text-destructive")
50 def from_form(self, raw: str | None) -> Result[bool | None, FieldError]:
51 if raw is None:
52 return Ok(None)
53 stripped = raw.strip()
54 if not stripped:
55 if self.nullable:
56 return Ok(None)
57 return Err(FieldError("Must be true or false"))
58 lower = stripped.lower()
59 if lower in ("true", "1", "yes"):
60 return Ok(True)
61 if lower in ("false", "0", "no"):
62 return Ok(False)
63 return Err(FieldError("Must be true or false"))
65 def to_form(self, value: bool | None) -> str:
66 if value is None:
67 return ""
68 return "true" if value else "false"