From e86a5dede4681b1f7315d4a33cc86b6f73e56ecd Mon Sep 17 00:00:00 2001 From: 7000pctAUTO Date: Mon, 2 Feb 2026 07:02:26 +0000 Subject: [PATCH] fix: add type annotations to examples and wizard --- regex_humanizer/wizard/__init__.py | 81 ++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 regex_humanizer/wizard/__init__.py diff --git a/regex_humanizer/wizard/__init__.py b/regex_humanizer/wizard/__init__.py new file mode 100644 index 0000000..6946e37 --- /dev/null +++ b/regex_humanizer/wizard/__init__.py @@ -0,0 +1,81 @@ +"""Interactive wizard module for building regex patterns step by step.""" + +from typing import Any, List, Optional + +from ..converter import convert_to_english + +WIZARD_STEPS = [ + { + "id": "pattern_type", + "name": "Pattern Type", + "description": "What type of pattern are you building?", + "options": [ + ("literal", "Match specific text"), + ("character_class", "Match a character set"), + ("template", "Use a template"), + ], + }, + { + "id": "quantifier", + "name": "Quantifier", + "description": "How many times should the pattern repeat?", + "options": [ + ("once", "Exactly once (default)"), + ("optional", "Zero or one time (?)"), + ("zero_or_more", "Zero or more times (*)"), + ("one_or_more", "One or more times (+)"), + ("custom", "Custom count"), + ], + }, +] + + +def get_step_prompt(step_id: str) -> Optional[dict]: + """Get the prompt for a wizard step.""" + for step in WIZARD_STEPS: + if step["id"] == step_id: + return step + return None + + +def get_step_options(step_id: str) -> Any: + """Get the options for a wizard step.""" + step = get_step_prompt(step_id) + if step: + return step.get("options", []) + return [] + + +def format_pattern_preview(parts: List[dict]) -> str: + """Format the current pattern as a preview string.""" + pattern_parts = [] + for part in parts: + if part["type"] == "literal": + pattern_parts.append(part["value"]) + elif part["type"] == "character_class": + chars = "".join(part["characters"]) + pattern_parts.append(f"[{chars}]") + elif part["type"] == "quantifier": + if pattern_parts: + pattern_parts[-1] = pattern_parts[-1] + part["value"] + return "".join(pattern_parts) + + +def get_pattern_description(parts: List[dict]) -> str: + """Get a human-readable description of the current pattern.""" + if not parts: + return "No pattern defined yet" + + pattern = format_pattern_preview(parts) + return convert_to_english(pattern) if pattern else "No pattern defined yet" + + +def validate_pattern_part(part: dict) -> tuple[bool, Optional[str]]: + """Validate a pattern part.""" + if part["type"] == "literal": + if not part.get("value"): + return False, "Literal value cannot be empty" + elif part["type"] == "character_class": + if not part.get("characters"): + return False, "Character class must have at least one character" + return True, None