br-fields 2.2.6

This is a shortcut tool related to database fields
Documentation
# AGENTS.md - br-fields

> Database field standardization library for Rust. Generates SQL DDL for SQLite, MySQL, and PostgreSQL.

## Quick Reference

```bash
# Build & Test
cargo build
cargo test                           # Run all tests
cargo test -- --nocapture            # Show println! output

# Lint & Format
cargo clippy --all-targets --all-features -- -D warnings
cargo fmt --check
```

## Structure

```
br-fields/
├── Cargo.toml          # Package manifest (edition 2021, v2.2.5)
├── src/
│   ├── lib.rs          # Field trait, FieldMode enum, field() & verify()
│   ├── str.rs          # Str, Pass, Key, Tel, Email, Code, BarCode, QrCode, Ident, Color
│   ├── int.rs          # Int, Switch
│   ├── float.rs        # Float
│   ├── text.rs         # Text, Editor, Json, Array, Object, Url
│   ├── datetime.rs     # Year, YearMonth, Datetime, Time, Date, Timestamp
│   ├── select.rs       # Radio, Select
│   ├── dict.rs         # Dict
│   ├── files.rs        # Files
│   ├── location.rs     # Location, Polygon
│   └── table.rs        # Table, Tree
└── tests/test.rs       # Integration tests
```

## Database SQL Generation

| DB | Field Quoting | NOT NULL | Metadata |
|----|---------------|----------|----------|
| `sqlite` | unquoted | Yes (when require=true) | None |
| `pgsql` | `"field"` | **NO** (never added) | `-- comment` |
| `mysql` | `` `field` `` | Yes (when require=true) | `comment '...'` |

**PostgreSQL special behavior:** `not null` is NEVER added for pgsql, even when `require=true`. This allows inserting records without specifying all fields.

## Code Patterns

### Adding New Field Type
1. Create struct with: `require`, `field`, `mode`, `title`, `def`, `show`, `describe`, `example`
2. Implement `new()` constructor
3. Implement `Field` trait (`sql()`, `hide()`, `describe()`, `field()`, `swagger()`, `example()`)
4. Add to `FieldMode` enum in `lib.rs`
5. Add match arms in `field()` and `verify()` functions
6. Add tests in `tests/test.rs`

### SQL Method Pattern
```rust
fn sql(&mut self, model: &str) -> String {
    let not_null = if self.require { " not null" } else { "" };
    match model {
        "sqlite" => format!("{} TYPE{} default ...", self.field, not_null),
        "pgsql" => {
            // NO not_null for pgsql
            let sql = format!(r#""{}" TYPE default ..."#, self.field);
            format!("{} --metadata", sql)
        }
        _ => {  // MySQL
            let sql = format!("`{}` TYPE{} default ...", self.field, not_null);
            format!("{} comment 'metadata'", sql)
        }
    }
}
```

### Test Pattern
```rust
// sqlite/mysql: exact string match
assert_eq!("expected sql", res);

// pgsql: use contains() for flexibility
assert!(res.contains(r#""field" TYPE"#));
assert!(!res.contains("not null"));  // Verify no not null
assert!(res.contains("--metadata"));
```

## Conventions

- **Doc comments:** Chinese language (`/// 中文描述`)
- **Imports:** std → external crates → internal (`use crate::...`)
- **Naming:** PascalCase structs, snake_case functions/fields
- **Error handling:** `.unwrap()` for JSON ops (assumes valid data)
- **Regex:** Use `lazy_static!` for compiled patterns

## Dependencies

| Crate | Purpose |
|-------|---------|
| `json` | JSON serialization |
| `chrono` | Date/time handling |
| `rand` | Random generation |
| `lazy_static` | Static initialization |
| `regex` | Pattern matching |
| `log` | Logging facade |