# cooklang-find

A Rust library for finding and managing [Cooklang](https://cooklang.org/) recipes in the filesystem. This library provides functionality to search, organize, and manage your recipe collection efficiently.

## Features

- **Recipe Search**: Find recipes by name or content across multiple directories
- **Recipe Tree**: Build and navigate a hierarchical structure of your recipe collection
- **Metadata Support**: Parse and access recipe metadata using the new frontmatter format
- **Title Image Support**: Automatically find and associate images with recipes
- **Error Handling**: Comprehensive error handling with custom error types

## Installation

Add this to your `Cargo.toml`:

```toml
[dependencies]
cooklang-find = "0.5.1"
```

### iOS (Swift Package Manager)

Add to your Xcode project or `Package.swift`:

```swift
.package(url: "https://github.com/cooklang/cooklang-find", from: "0.5.1")
```

### Android (GitHub Packages)

Add to your `build.gradle.kts`:

```kotlin
implementation("org.cooklang:cooklang-find:0.5.1")
```

See [BINDINGS.md](BINDINGS.md) for detailed mobile integration instructions.

## Usage

### Finding a Recipe

```rust
use cooklang_find::get_recipe;
use std::path::Path;

// Search for a recipe in multiple directories
let recipe_dirs = vec![
    Path::new("~/recipes"),
    Path::new("~/more-recipes")
];

match get_recipe(recipe_dirs, Path::new("pancakes")) {
    Ok(Some(recipe)) => println!("Found recipe: {}", recipe.name),
    Ok(None) => println!("Recipe not found"),
    Err(e) => eprintln!("Error: {}", e),
}
```

### Building a Recipe Tree

```rust
use cooklang_find::build_tree;
use std::path::Path;

// Build a tree structure of your recipe collection
match build_tree(Path::new("~/recipes")) {
    Ok(tree) => {
        // Access recipes and subdirectories
        for (name, node) in tree.children {
            if let Some(recipe) = node.recipe {
                println!("Found recipe: {}", recipe.name);
            } else {
                println!("Found directory: {}", name);
            }
        }
    }
    Err(e) => eprintln!("Error: {}", e),
}
```

### Searching Recipes

```rust
use cooklang_find::search;
use std::path::Path;

// Search for recipes containing specific text
match search(Path::new("~/recipes"), "pancake") {
    Ok(recipes) => {
        for recipe in recipes {
            println!("Found matching recipe: {}", recipe.name);
        }
    }
    Err(e) => eprintln!("Error: {}", e),
}
```

## Recipe Format

The library supports Cooklang recipes with frontmatter metadata. Example:

```cooklang
---
servings: 4
time: 30 min
cuisine: Italian
---

Prepare the @pasta{500%g} by boiling it in @water{2%l}.
Add @salt{1%tsp} to taste.
```

## Features in Detail

### Recipe Search
- Search by filename or content
- Case-insensitive matching
- Support for multiple search directories
- Priority-based search (first directory match wins)

### Recipe Tree
- Build hierarchical structure of recipes
- Support for nested directories
- Easy navigation of recipe collection
- Automatic directory creation and management

### Metadata Support
- Parse frontmatter metadata
- Access common fields (servings, time, cuisine)
- Support for custom metadata fields
- Cached metadata access for performance

### Title Image Support
- Automatic discovery of recipe images
- Support for multiple image formats (jpg, jpeg, png, webp)
- Case-insensitive extension matching
- Automatic association with recipes

## Error Handling

The library provides custom error types for different scenarios:

- `FetchError`: Issues with finding recipes
- `RecipeEntryError`: Problems with recipe parsing or reading
- `TreeError`: Errors in building recipe tree structure
- `SearchError`: Issues during recipe search

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

This project is licensed under the MIT License - see the LICENSE file for details.

## Acknowledgments

- [Cooklang](https://cooklang.org/) - The recipe markup language
- [cooklang-rs](https://crates.io/crates/cooklang) - Rust implementation of Cooklang parser
