Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ jobs:
with:
elixir-version: ${{ matrix.elixir }}
otp-version: ${{ matrix.otp }}
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
- name: Restore deps and _build cache
uses: actions/cache@v5
with:
Expand Down Expand Up @@ -73,6 +75,8 @@ jobs:
with:
elixir-version: "1.18.4"
otp-version: "26.2.5"
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
- name: Restore dependencies cache
uses: actions/cache@v5
with:
Expand Down
32 changes: 32 additions & 0 deletions .github/workflows/native.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Native (Rust NIF)
on:
push:
branches: [main]
paths: ["native/**", ".github/workflows/native.yml"]
pull_request:
branches: [main]
paths: ["native/**", ".github/workflows/native.yml"]
workflow_dispatch:
permissions:
contents: read
jobs:
lint-and-test:
name: fmt + clippy + test
runs-on: ubuntu-latest
defaults:
run:
working-directory: native/arke_native
steps:
- uses: actions/checkout@v6
- uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- uses: Swatinem/rust-cache@v2
with:
workspaces: native/arke_native
- name: Format
run: cargo fmt --all --check
- name: Clippy
run: cargo clippy --all-targets -- -D warnings
- name: Test
run: cargo test
78 changes: 78 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: Release NIF binaries
on:
push:
tags: ["v*"]
workflow_dispatch:
inputs:
tag:
description: "Tag to build binaries for (e.g. v0.6.1)"
required: true

permissions:
contents: write

jobs:
build:
name: ${{ matrix.target }}
runs-on: ${{ matrix.runner }}
defaults:
run:
working-directory: native/arke_native
strategy:
fail-fast: false
matrix:
include:
- target: x86_64-unknown-linux-gnu
runner: ubuntu-latest
cross: true
- target: aarch64-unknown-linux-gnu
runner: ubuntu-latest
cross: true
- target: aarch64-apple-darwin
runner: macos-14
cross: false
env:
NIF_VERSION: "2.15"
steps:
- uses: actions/checkout@v6

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

- uses: taiki-e/install-action@v2
if: matrix.cross
with:
tool: cross

- name: Resolve version
id: ver
shell: bash
run: |
ref="${{ github.event.inputs.tag || github.ref_name }}"
echo "version=${ref#v}" >> "$GITHUB_OUTPUT"

- name: Build
shell: bash
run: |
if [ "${{ matrix.cross }}" = "true" ]; then
cross build --release --target ${{ matrix.target }}
else
cargo build --release --target ${{ matrix.target }}
fi

- name: Package
shell: bash
run: |
v="${{ steps.ver.outputs.version }}"
out="target/${{ matrix.target }}/release"
src="$out/libarke_native.so"
[ -f "$src" ] || src="$out/libarke_native.dylib"
name="libarke_native-v${v}-nif-${NIF_VERSION}-${{ matrix.target }}.so"
cp "$src" "$name"
tar -czf "${name}.tar.gz" "$name"

- uses: softprops/action-gh-release@v3
with:
tag_name: ${{ github.event.inputs.tag || github.ref_name }}
files: native/arke_native/*.so.tar.gz
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,7 @@ arke-*.tar
.elixir_ls/
.idea/
.idea

# Rust NIF build artifacts
native/*/target/
priv/native/
42 changes: 42 additions & 0 deletions lib/arke/native/date_parser.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Copyright 2023 Arkemis S.r.l.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

defmodule Arke.Native.DateParser do
@moduledoc """
Rust NIFs for ISO8601 parsing and month arithmetic. Binary in, integer
tuples out (`nil` on failure); the caller rebuilds the structs.

If the NIF isn't loaded, functions raise `:nif_not_loaded`;
`Arke.Utils.DatetimeHandler` rescues that and falls back to pure Elixir.
"""
@version Mix.Project.config()[:version]

use RustlerPrecompiled,
otp_app: :arke,
crate: "arke_native",
base_url: "https://github.com/arkemis/arke/releases/download/v#{@version}",
version: @version,
targets: ~w(
x86_64-unknown-linux-gnu
aarch64-unknown-linux-gnu
aarch64-apple-darwin
),
# download the binary instead of building once a release + checksum exist
force_build: System.get_env("ARKE_FORCE_BUILD_NIF", "true") in ["1", "true"]

def parse_date(_binary), do: :erlang.nif_error(:nif_not_loaded)
def parse_time(_binary), do: :erlang.nif_error(:nif_not_loaded)
def parse_datetime(_binary), do: :erlang.nif_error(:nif_not_loaded)
def add_months(_y, _m, _d, _months), do: :erlang.nif_error(:nif_not_loaded)
end
Loading