aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/FEATURE_DEVELOPMENT_EXAMPLE.md
diff options
context:
space:
mode:
Diffstat (limited to 'FEATURE_DEVELOPMENT_EXAMPLE.md')
-rw-r--r--FEATURE_DEVELOPMENT_EXAMPLE.md298
1 files changed, 298 insertions, 0 deletions
diff --git a/FEATURE_DEVELOPMENT_EXAMPLE.md b/FEATURE_DEVELOPMENT_EXAMPLE.md
new file mode 100644
index 0000000..838d0c4
--- /dev/null
+++ b/FEATURE_DEVELOPMENT_EXAMPLE.md
@@ -0,0 +1,298 @@
+# OneRoll 功能开发示例:注释功能
+
+本文档展示了如何为 OneRoll 项目添加新功能的完整开发流程,以添加注释功能为例。
+
+## 功能需求
+
+添加注释功能,允许用户在骰子表达式末尾使用 `#` 添加注释,返回结果中包含注释信息。
+
+**示例:**
+- `3d6 + 2 # 攻击投掷` → 返回 `{'total': 14, 'comment': '攻击投掷', ...}`
+- `4d6kh3 # 属性投掷` → 返回 `{'total': 15, 'comment': '属性投掷', ...}`
+
+## 开发步骤
+
+### 1. 更新语法定义 (grammar.pest)
+
+```pest
+// 添加注释规则
+comment = { "#" ~ (!"\n" ~ ANY)* }
+
+// 修改主表达式规则以支持可选注释
+dice_expr = { dice_term ~ (op ~ dice_term)* ~ comment? }
+```
+
+### 2. 更新类型定义 (types.rs)
+
+```rust
+// 为 DiceResult 添加注释字段
+#[derive(Debug, Clone, Serialize, Deserialize)]
+pub struct DiceResult {
+ pub expression: String,
+ pub total: i32,
+ pub rolls: Vec<Vec<i32>>,
+ pub details: String,
+ pub comment: Option<String>, // 新增字段
+}
+
+// 为 Expression 添加注释变体
+#[derive(Debug, Clone)]
+pub enum Expression {
+ // ... 现有变体
+ WithComment(Box<Expression>, Option<String>), // 新增变体
+}
+```
+
+### 3. 更新解析器 (parser.rs)
+
+```rust
+// 添加注释解析函数
+fn parse_comment(pair: pest::iterators::Pair<Rule>) -> Result<Option<String>, DiceError> {
+ match pair.as_rule() {
+ Rule::comment => {
+ let comment = pair.as_str().trim_start_matches('#').trim();
+ Ok(if comment.is_empty() { None } else { Some(comment.to_string()) })
+ }
+ _ => Ok(None),
+ }
+}
+
+// 修改主解析逻辑以处理注释
+Rule::dice_expr => {
+ let mut pairs = pair.into_inner();
+ let mut expr = Self::parse_dice_term(pairs.next().unwrap())?;
+
+ while let Some(pair) = pairs.next() {
+ match pair.as_rule() {
+ Rule::op => {
+ // ... 操作符处理逻辑
+ }
+ Rule::comment => {
+ let comment = Self::parse_comment(pair)?;
+ if let Some(comment_text) = comment {
+ expr = Expression::WithComment(Box::new(expr), Some(comment_text));
+ }
+ }
+ _ => {}
+ }
+ }
+ Ok(expr)
+}
+```
+
+### 4. 更新计算器 (calculator.rs)
+
+```rust
+// 为所有 DiceResult 创建添加 comment: None
+Expression::Number(n) => Ok(DiceResult {
+ expression: n.to_string(),
+ total: *n,
+ rolls: vec![],
+ details: format!("{}", n),
+ comment: None, // 新增
+}),
+
+// 添加注释处理逻辑
+Expression::WithComment(expr, comment) => {
+ let mut result = self.evaluate_expression(expr)?;
+ result.comment = comment.clone();
+ Ok(result)
+}
+```
+
+### 5. 更新 Python 绑定 (python_bindings.rs)
+
+```rust
+// 在所有返回字典中添加注释字段
+let dict = PyDict::new(py);
+dict.set_item("expression", &result.expression)?;
+dict.set_item("total", result.total)?;
+dict.set_item("rolls", result.rolls)?;
+dict.set_item("details", &result.details)?;
+dict.set_item("comment", result.comment.as_deref().unwrap_or(""))?; // 新增
+
+Ok(dict.into())
+```
+
+### 6. 更新类型注解 (_core.pyi)
+
+```python
+def roll_dice(expression: str) -> Dict[str, Any]:
+ """
+ 解析并计算骰子表达式
+
+ Returns:
+ 包含以下键的字典:
+ - expression: str - 表达式字符串
+ - total: int - 总点数
+ - rolls: List[List[int]] - 投掷结果列表
+ - details: str - 详细信息
+ - comment: str - 用户注释 # 新增
+ """
+ ...
+```
+
+### 7. 更新 Python 接口 (__init__.py)
+
+```python
+def roll(expression: str) -> Dict[str, Any]:
+ """
+ 解析并计算骰子表达式(便捷函数)
+
+ Args:
+ expression: 骰子表达式字符串,支持注释
+
+ Returns:
+ 投掷结果字典,包含 comment 字段
+
+ Example:
+ result = oneroll.roll("3d6 + 2 # 攻击投掷")
+ print(result["comment"]) # 输出: "攻击投掷"
+ """
+ return _roll_dice(expression)
+```
+
+### 8. 更新用户界面
+
+#### 命令行界面 (__main__.py)
+```python
+def print_result(self, result: Dict[str, Any], expression: str = None):
+ """美化打印投掷结果"""
+ # ... 现有逻辑
+
+ # 显示注释
+ comment = result.get("comment", "")
+ if comment:
+ text.append(f"\n注释: ", style="bold")
+ text.append(f"{comment}", style="italic blue")
+
+ panel = Panel(text, title="投掷结果", border_style=color)
+ console.print(panel)
+```
+
+#### TUI 界面 (tui.py)
+```python
+def show_result(self, result: Dict[str, Any], expression: str) -> None:
+ """显示投掷结果"""
+ # ... 现有逻辑
+
+ # 显示注释
+ comment = result.get("comment", "")
+ if comment:
+ display_text += f"\n\n[bold]注释:[/bold] [italic blue]{comment}[/italic blue]"
+
+ self.update(display_text)
+```
+
+## 构建和测试
+
+### 构建项目
+```bash
+maturin develop
+```
+
+### 测试新功能
+```python
+# 基本测试
+import oneroll
+result = oneroll.roll("3d6 + 2 # 攻击投掷")
+print(f"总点数: {result['total']}, 注释: {result['comment']}")
+
+# 命令行测试
+python -m oneroll "4d6kh3 # 属性投掷"
+
+# 复杂表达式测试
+python -c "import oneroll; print(oneroll.roll('2d6! # 爆炸骰子攻击'))"
+```
+
+## 测试结果
+
+```
+总点数: 14, 注释: 攻击投掷
+```
+
+```
+╭──────────────────────────────────────────────── 投掷结果 ────────────────────────────────────────────────╮
+│ 🎲 4d6 │
+│ 总点数: 13 │
+│ 详情: 4d6kh3 = 13 (详情: [[5], [4], [4]]) │
+│ 投掷结果: [[5], [4], [4]] │
+│ 注释: 属性投掷 │
+╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+```
+
+## 开发要点
+
+### 1. 模块化开发
+- 每个功能都在相应的模块中实现
+- 保持代码的清晰结构和职责分离
+
+### 2. 类型安全
+- 所有新功能都有完整的类型注解
+- 使用 Option<T> 处理可选字段
+
+### 3. 向后兼容
+- 新功能不影响现有 API
+- 可选字段使用默认值
+
+### 4. 用户体验
+- 更新所有用户界面以显示新功能
+- 提供清晰的文档和示例
+
+### 5. 错误处理
+- 处理边界情况(如空注释)
+- 保持现有的错误处理机制
+
+## 扩展建议
+
+### 1. 注释验证
+```rust
+// 可以添加注释长度限制
+if comment.len() > MAX_COMMENT_LENGTH {
+ return Err(DiceError::InvalidExpression("注释过长".to_string()));
+}
+```
+
+### 2. 注释格式化
+```rust
+// 可以添加注释格式化选项
+pub struct CommentOptions {
+ pub max_length: usize,
+ pub allow_special_chars: bool,
+ pub trim_whitespace: bool,
+}
+```
+
+### 3. 注释统计
+```python
+# 可以添加注释相关的统计功能
+def get_comment_statistics(results: List[Dict[str, Any]]) -> Dict[str, Any]:
+ """分析注释使用情况"""
+ comments = [r.get('comment', '') for r in results if r.get('comment')]
+ return {
+ 'total_comments': len(comments),
+ 'unique_comments': len(set(comments)),
+ 'most_common': max(set(comments), key=comments.count) if comments else None
+ }
+```
+
+## 总结
+
+这个示例展示了为 OneRoll 项目添加新功能的完整流程:
+
+1. **语法定义** → 定义新语法规则
+2. **类型定义** → 添加新的数据结构
+3. **解析器** → 实现解析逻辑
+4. **计算器** → 处理新功能
+5. **Python 绑定** → 暴露给 Python
+6. **类型注解** → 提供类型信息
+7. **Python 接口** → 更新文档和示例
+8. **用户界面** → 在所有界面中支持新功能
+
+这种模块化的开发方式确保了:
+- 代码的可维护性
+- 功能的完整性
+- 用户体验的一致性
+- 向后兼容性
+
+通过这个流程,你可以轻松地为 OneRoll 添加更多功能,如自定义修饰符、条件表达式、变量支持等。