Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c0e4782
docs: openrail onboarding document
MathiasVDA May 13, 2026
31a3d8e
specs: created specs for .net interface
MathiasVDA May 13, 2026
ec0b87b
specs: created technical plan for .net interface
MathiasVDA May 13, 2026
528b8a6
specs: add tasks for .net interface
MathiasVDA May 13, 2026
893de6b
feat: implemented .net interface
MathiasVDA May 13, 2026
7c27f03
chore: fix linting
MathiasVDA May 13, 2026
1db55b1
chore: fix failing tests on github
MathiasVDA May 13, 2026
e55f4ed
ci: only run benchmark when releasing
MathiasVDA May 13, 2026
c9582c7
chore: fix more linting issues
MathiasVDA May 13, 2026
367e2df
chore: fix more linting issues
MathiasVDA May 13, 2026
b54bcdd
feat(tp-net): add end-to-end CSV support for GNSS input
Copilot May 13, 2026
231023c
refactor(tp-net): choose GNSS parser by payload format
Copilot May 13, 2026
76385b8
chore: add tests for parse_gnss_csv_str
MathiasVDA May 13, 2026
75c1f9c
Merge branch '005-dotnet-bindings' of github.com:Matdata-eu/tp-lib in…
MathiasVDA May 13, 2026
1da2bcf
fix: used wrong navigability values
MathiasVDA May 13, 2026
2c84283
ci: set version before packing
MathiasVDA May 13, 2026
187198f
chore: implement review comment
MathiasVDA May 13, 2026
86b1b48
chore: remove .NET build artifacts and update .gitignore
MathiasVDA May 13, 2026
9fd1834
chore: add invalid entry parameter checks
MathiasVDA May 13, 2026
494080f
feat: implement train detection record API
MathiasVDA May 13, 2026
b6bf912
chore: fix linting issue
MathiasVDA May 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions .github/agents/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# tp-lib Development Guidelines
# tp-lib Development Guidelines

Auto-generated from all feature plans. Last updated: 2026-01-09

Expand All @@ -7,6 +7,8 @@ Auto-generated from all feature plans. Last updated: 2026-01-09
- File-based (GeoJSON network, CSV train path, CSV GNSS positions) — no database (003-path-review-webapp)
- Rust 1.91.1+ (workspace edition 2021) + `geo` 0.28, `rstar` 0.12, `geojson` 0.24, `csv` 1.x, `serde`/`serde_json`, `chrono` (DateTime<FixedOffset>), `petgraph`, `proj4rs` 0.1.9; webapp: `axum`, `tokio`, Leaflet (static) (004-train-detections)
- File-based I/O (CSV / GeoJSON); no DB. R-tree (`rstar`) in-memory spatial index reused for coordinate resolution. (004-train-detections)
- Rust 1.75 (tp-net crate) + C# 12 / .NET 8 (TpLib managed) + `csbindgen` (FFI stub generation), `serde_json` (FFI marshalling), `tp-lib-core` (core algorithms); C# side: `System.Text.Json` (deserialization), xUnit (testing) (005-dotnet-bindings)
- N/A — stateless function calls only (005-dotnet-bindings)

- Rust 1.75+ (edition 2021) (002-train-path-calculation)

Expand All @@ -27,7 +29,7 @@ After **any** change to a `.rs` file in this workspace, always run these checks

1. `cargo fmt --check` — verify all Rust source is formatted with rustfmt.
Fix automatically with `cargo fmt` if there are diffs.
2. `cargo clippy --all-targets --all-features -- -D warnings` — zero-warning policy.
2. `cargo clippy --workspace --all-targets --all-features -- -D warnings` — zero-warning policy.
3. `cargo test --workspace` — full test suite must stay green.

For changes to `tp-py/` (Python bindings), also run:
Expand All @@ -41,10 +43,10 @@ For Python source files (`.py`) changed under `tp-py/`:
Rust 1.75+ (edition 2021): Follow standard conventions

## Recent Changes
- 005-dotnet-bindings: Added Rust 1.75 (tp-net crate) + C# 12 / .NET 8 (TpLib managed) + `csbindgen` (FFI stub generation), `serde_json` (FFI marshalling), `tp-lib-core` (core algorithms); C# side: `System.Text.Json` (deserialization), xUnit (testing)
- 004-train-detections: Added Rust 1.91.1+ (workspace edition 2021) + `geo` 0.28, `rstar` 0.12, `geojson` 0.24, `csv` 1.x, `serde`/`serde_json`, `chrono` (DateTime<FixedOffset>), `petgraph`, `proj4rs` 0.1.9; webapp: `axum`, `tokio`, Leaflet (static)
- 003-path-review-webapp: Added Rust 2021 edition, latest stable (1.80+)

- 002-train-path-calculation: Added Rust 1.75+ (edition 2021)

<!-- MANUAL ADDITIONS START -->
<!-- MANUAL ADDITIONS END -->
26 changes: 26 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
branches: [ main, develop ]
pull_request:
branches: [ main ]
release:
types: [ published ]

env:
CARGO_TERM_COLOR: always
Expand Down Expand Up @@ -44,6 +46,7 @@ jobs:
bench:
name: Benchmarks
runs-on: ubuntu-latest
if: github.event_name == 'release'
steps:
- uses: actions/checkout@v4

Expand Down Expand Up @@ -84,6 +87,29 @@ jobs:
- name: Run Python tests
run: .venv/bin/pytest tp-py/python/tests/

dotnet:
name: .NET Tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'

- name: Build native library
run: cargo build -p tp-lib-net

- name: Run cargo tests (tp-net)
run: cargo test -p tp-lib-net

- name: Run .NET tests
run: dotnet test tp-net/csharp/Tests/TpLib.Tests.csproj -c Debug --verbosity minimal

lint:
name: Linting
runs-on: ubuntu-latest
Expand Down
122 changes: 122 additions & 0 deletions .github/workflows/publish-nuget.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
name: Publish to NuGet

on:
release:
types: [published]
workflow_dispatch:

env:
CARGO_TERM_COLOR: always

permissions:
contents: read

jobs:
build-native:
name: Build native (${{ matrix.rid }})
runs-on: ${{ matrix.os }}
if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch'
strategy:
fail-fast: false
matrix:
include:
- rid: win-x64
os: windows-latest
target: x86_64-pc-windows-msvc
artifact: tp_lib_net.dll
- rid: linux-x64
os: ubuntu-latest
target: x86_64-unknown-linux-gnu
artifact: libtp_lib_net.so
- rid: osx-x64
os: macos-13
target: x86_64-apple-darwin
artifact: libtp_lib_net.dylib
- rid: osx-arm64
os: macos-latest
target: aarch64-apple-darwin
artifact: libtp_lib_net.dylib
steps:
- uses: actions/checkout@v4

- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}

- name: Build native library
run: cargo build --release -p tp-lib-net --target ${{ matrix.target }}

- name: Stage artifact
shell: bash
run: |
mkdir -p staging
cp target/${{ matrix.target }}/release/${{ matrix.artifact }} staging/

- name: Upload native artifact
uses: actions/upload-artifact@v4
with:
name: native-${{ matrix.rid }}
path: staging/${{ matrix.artifact }}

pack-and-publish:
name: Pack and publish to NuGet
needs: build-native
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch'
permissions:
contents: read
id-token: write # required for GitHub OIDC token issuance (trusted publishing)
steps:
- uses: actions/checkout@v4

- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.0.x'

- name: Download all native artifacts
uses: actions/download-artifact@v4
with:
path: native-artifacts

- name: Arrange runtimes
run: |
mkdir -p tp-net/csharp/runtimes/win-x64/native
mkdir -p tp-net/csharp/runtimes/linux-x64/native
mkdir -p tp-net/csharp/runtimes/osx-x64/native
mkdir -p tp-net/csharp/runtimes/osx-arm64/native
cp native-artifacts/native-win-x64/tp_lib_net.dll tp-net/csharp/runtimes/win-x64/native/
cp native-artifacts/native-linux-x64/libtp_lib_net.so tp-net/csharp/runtimes/linux-x64/native/
cp native-artifacts/native-osx-x64/libtp_lib_net.dylib tp-net/csharp/runtimes/osx-x64/native/
cp native-artifacts/native-osx-arm64/libtp_lib_net.dylib tp-net/csharp/runtimes/osx-arm64/native/

- name: Pack
run: |
if [[ "${GITHUB_REF}" == refs/tags/v* ]]; then
PACKAGE_VERSION="${GITHUB_REF_NAME#v}"
dotnet pack tp-net/csharp/TpLib.csproj -c Release -o nupkg -p:PackageVersion="${PACKAGE_VERSION}"
else
dotnet pack tp-net/csharp/TpLib.csproj -c Release -o nupkg
fi

- name: Upload nupkg
uses: actions/upload-artifact@v4
with:
name: nupkg
path: nupkg/*.nupkg

- name: NuGet login (OIDC trusted publishing)
if: startsWith(github.ref, 'refs/tags/v')
uses: NuGet/login@v1
id: nuget-login
with:
user: ${{ secrets.NUGET_USER }}

- name: Publish to NuGet
if: startsWith(github.ref, 'refs/tags/v')
run: |
dotnet nuget push "nupkg/*.nupkg" \
--api-key "${{ steps.nuget-login.outputs.NUGET_API_KEY }}" \
--source https://api.nuget.org/v3/index.json \
--skip-duplicate
59 changes: 59 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,65 @@ htmlcov/
# Logs
*.log

# .NET
[Bb]in/
[Oo]bj/
*.user
*.suo
*.userosscache
*.sln.docstates
*.userprefs
.vs/
*.ncrunch*
*.[Rr]e[Ss]harper
*.DotSettings.user
[Dd]ebug/
[Rr]elease/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
*.VisualState.xml
TestResult.xml
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
*.nupkg
*.snupkg
*.coverage
*.coveragexml
_NCrunch_*
MightyCruise_Crash.txt
.localhistory/
*.vs/
# OS
Thumbs.db

Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ members = [
"tp-cli",
"tp-py",
"tp-webapp",
"tp-net",
]
resolver = "2"

Expand Down
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
[![codecov](https://codecov.io/gh/matdata-eu/tp-lib/branch/main/graph/badge.svg)](https://codecov.io/gh/matdata-eu/tp-lib)
[![crates.io](https://img.shields.io/crates/v/tp-lib-core.svg)](https://crates.io/crates/tp-lib-core)
[![PyPI](https://img.shields.io/pypi/v/tp-lib.svg)](https://pypi.org/project/tp-lib/)
[![NuGet](https://img.shields.io/nuget/v/TpLib.svg)](https://www.nuget.org/packages/TpLib/)
[![Documentation](https://img.shields.io/badge/docs-github.io-blue)](https://matdata-eu.github.io/tp-lib/)
[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)

Expand Down Expand Up @@ -155,7 +156,8 @@ tp-lib/ # Rust workspace root
│ └── benches/ # Performance benchmarks
├── tp-cli/ # Command-line interface
├── tp-webapp/ # Interactive path review web server (axum + Leaflet.js)
└── tp-py/ # Python bindings (PyO3)
├── tp-py/ # Python bindings (PyO3)
└── tp-net/ # .NET bindings (csbindgen + System.Text.Json)
```

## Quick Start
Expand Down Expand Up @@ -431,6 +433,7 @@ The documentation is automatically built and deployed on every push to `main`. I
- **tp-core**: Core library API with examples
- **tp-cli**: Command-line interface documentation
- **tp-py**: Python bindings API reference
- **tp-net**: .NET bindings API reference

**Build locally:**

Expand Down Expand Up @@ -499,7 +502,7 @@ This project follows the TP-Lib Constitution v1.1.0 principles:
- ✅ **VII. CRS Explicit**: All coordinates include CRS specification
- ✅ **VIII. Error Handling**: Typed errors with thiserror, fail-fast validation
- ✅ **IX. Data Provenance**: Preserve original GNSS data, audit logging
- ✅ **X. Integration Flexibility**: Rust API + CLI + Python bindings
- ✅ **X. Integration Flexibility**: Rust API + CLI + Python bindings + .NET bindings

## Contributing

Expand Down
Loading
Loading