# `Yog.IO.Libgraph`
[🔗](https://github.com/code-shoily/yog_ex/blob/v0.97.0/lib/yog/io/libgraph.ex#L1)

Interoperability with the [libgraph](https://hex.pm/packages/libgraph) library.

This module provides bidirectional conversion between Yog graphs and Libgraph graphs,
enabling users to leverage both libraries' algorithms on the same graph data.

## Installation

To use this module, add `libgraph` to your dependencies:

    defp deps do
      [
        {:yog_ex, "~> 0.90.0"},
        {:libgraph, "~> 0.16"}  # Required for interoperability
      ]
    end

## Type Mapping

| Yog Type | Libgraph Type | Notes |
|----------|---------------|-------|
| `Yog.Graph` (directed) | `Graph` with `:directed` type | Standard directed graph |
| `Yog.Graph` (undirected) | `Graph` with `:undirected` type | Standard undirected graph |
| `Yog.Multi.Graph` | `Graph` with parallel edges | Multi-graph support |
| `Yog.DAG` | `Graph` (acyclic) | DAG type preserved |

## Examples

### Convert Yog to Libgraph

    iex> graph = Yog.directed()
    ...> |> Yog.add_node(1, "A")
    ...> |> Yog.add_node(2, "B")
    ...> |> Yog.add_edge_ensure(from: 1, to: 2, with: 5)
    iex> libgraph = Yog.IO.Libgraph.to_libgraph(graph)
    iex> libgraph.type
    :directed

### Convert Libgraph to Yog

### DAG Conversion

    iex> {:ok, dag} = Yog.DAG.from_graph(
    ...>   Yog.directed()
    ...>   |> Yog.add_node(1, nil)
    ...>   |> Yog.add_node(2, nil)
    ...>   |> Yog.add_edge_ensure(1, 2, 1)
    ...> )
    iex> libgraph = Yog.IO.Libgraph.to_libgraph(dag)
    iex> {:ok, yog_dag} = Yog.IO.Libgraph.from_libgraph(libgraph)
    iex> %Yog.DAG{} = yog_dag

## Error Handling

- `{:ok, graph}` - Successful conversion
- `{:error, reason}` - Conversion failed (e.g., cycle detected when creating DAG)

# `from_libgraph`

```elixir
@spec from_libgraph(
  Graph.t(),
  keyword()
) :: {:ok, Yog.Graph.t() | Yog.Multi.Graph.t() | Yog.DAG.t()} | {:error, atom()}
```

Converts a Libgraph graph to the appropriate Yog graph type.

The returned type depends on the Libgraph graph structure:
- Simple directed/undirected → `Yog.Graph`
- Multi-edges detected → `Yog.Multi.Graph`
- Acyclic → `Yog.DAG` (if validation passes)

## Options

  * `:force_type` - Override automatic type detection (`:simple`, `:multi`, `:dag`)

## Examples

    iex> libgraph = Graph.new(type: :directed)
    ...> |> Graph.add_vertex(1, "data")
    ...> |> Graph.add_vertex(2, "more")
    ...> |> Graph.add_edge(1, 2, weight: 10)
    iex> {:ok, graph} = Yog.IO.Libgraph.from_libgraph(libgraph, force_type: :simple)
    iex> Yog.Model.order(graph) == 2
    true

# `to_libgraph`

```elixir
@spec to_libgraph(
  Yog.Graph.t() | Yog.Multi.Graph.t() | Yog.DAG.t(),
  keyword()
) :: Graph.t()
```

Converts a Yog graph to a Libgraph graph.

Automatically detects the appropriate Libgraph configuration based on input type.

## Examples

    iex> graph = Yog.undirected()
    ...> |> Yog.add_node(1, "A")
    ...> |> Yog.add_node(2, "B")
    ...> |> Yog.add_edge_ensure(1, 2, 5)
    iex> libgraph = Yog.IO.Libgraph.to_libgraph(graph)
    iex> libgraph.type
    :undirected

---

*Consult [api-reference.md](api-reference.md) for complete listing*
