diff --git a/lib/zenohex.ex b/lib/zenohex.ex index 902a0a9..3c97c97 100644 --- a/lib/zenohex.ex +++ b/lib/zenohex.ex @@ -1,13 +1,20 @@ defmodule Zenohex do @moduledoc """ - Documentation for `Zenohex`. + Documentation for `#{__MODULE__}`. """ - @doc """ + alias Zenohex.Nif + alias Zenohex.Session + @doc ~S""" + Open a zenoh Session. + + ## Examples + + iex> Zenohex.open!() """ - @spec open :: NifZenoh.session() - def open do - NifZenoh.zenoh_open() + @spec open! :: Session.t() + def open!() do + Nif.zenoh_open() end end diff --git a/lib/zenohex/nif.ex b/lib/zenohex/nif.ex index c00c9c8..06c5c31 100644 --- a/lib/zenohex/nif.ex +++ b/lib/zenohex/nif.ex @@ -1,4 +1,6 @@ defmodule Zenohex.Nif do + @moduledoc false + use Rustler, otp_app: :zenohex, crate: "zenohex_nif" alias Zenohex.Publisher diff --git a/lib/zenohex/publisher.ex b/lib/zenohex/publisher.ex index bea740f..4da4212 100644 --- a/lib/zenohex/publisher.ex +++ b/lib/zenohex/publisher.ex @@ -1,21 +1,42 @@ defmodule Zenohex.Publisher do + @moduledoc """ + Documentation for `#{__MODULE__}`. + """ + alias Zenohex.Nif @type t :: reference() - @type congestion_control :: :drop | :block - @type priority :: - :real_time - | :interactive_high - | :interactive_low - | :data_high - | :data - | :data_low - | :background defmodule Options do + @moduledoc """ + Documentation for `#{__MODULE__}`. + """ + + @type t :: %__MODULE__{congestion_control: congestion_control(), priority: priority()} + @type congestion_control :: :drop | :block + @type priority :: + :real_time + | :interactive_high + | :interactive_low + | :data_high + | :data + | :data_low + | :background + defstruct congestion_control: :drop, priority: :data end + @doc ~S""" + Put data. + + ## Examples + + iex> session = Zenohex.open!() + iex> publisher = Zenohex.Session.declare_publisher!(session, "key/expression") + iex> :ok = Zenohex.Publisher.put!(publisher, "value") + iex> :ok = Zenohex.Publisher.put!(publisher, 0) + iex> :ok = Zenohex.Publisher.put!(publisher, 0.0) + """ @spec put!(t(), binary()) :: :ok def put!(publisher, value) when is_binary(value) do Nif.publisher_put_binary(publisher, value) @@ -31,17 +52,44 @@ defmodule Zenohex.Publisher do Nif.publisher_put_float(publisher, value) end + @doc ~S""" + Delete data. + + ## Examples + + iex> session = Zenohex.open!() + iex> publisher = Zenohex.Session.declare_publisher!(session, "key/expression") + iex> :ok = Zenohex.Publisher.delete!(publisher) + """ @spec delete!(t()) :: :ok def delete!(publisher) do Nif.publisher_delete(publisher) end - @spec congestion_control!(t(), congestion_control()) :: t() + @doc ~S""" + Change the congestion_control to apply when routing the data. + + ## Examples + + iex> session = Zenohex.open!() + iex> publisher = Zenohex.Session.declare_publisher!(session, "key/expression") + iex> Zenohex.Publisher.congestion_control!(publisher, :drop) + """ + @spec congestion_control!(t(), Options.congestion_control()) :: t() def congestion_control!(publisher, congestion_control) do Nif.publisher_congestion_control(publisher, congestion_control) end - @spec priority!(t(), priority()) :: t() + @doc ~S""" + Change the priority of the written data. + + ## Examples + + iex> session = Zenohex.open!() + iex> publisher = Zenohex.Session.declare_publisher!(session, "key/expression") + iex> Zenohex.Publisher.priority!(publisher, :real_time) + """ + @spec priority!(t(), Options.priority()) :: t() def priority!(publisher, priority) do Nif.publisher_priority(publisher, priority) end diff --git a/lib/zenohex/pull_subscriber.ex b/lib/zenohex/pull_subscriber.ex index 0ae5c9a..3cb5130 100644 --- a/lib/zenohex/pull_subscriber.ex +++ b/lib/zenohex/pull_subscriber.ex @@ -1,15 +1,40 @@ defmodule Zenohex.PullSubscriber do + @moduledoc """ + Documentation for `#{__MODULE__}`. + """ + alias Zenohex.Nif @type t :: reference() + @doc """ + Pull data. + + ## Examples + + iex> session = Zenohex.open!() + iex> subscriber = Zenohex.Session.declare_pull_subscriber!(session, "key/expression") + iex> Zenohex.PullSubscriber.pull!(subscriber) + :ok + """ @spec pull!(t()) :: :ok - def pull!(pull_subscriber) do + def pull!(pull_subscriber) when is_reference(pull_subscriber) do Nif.pull_subscriber_pull(pull_subscriber) end - @spec recv_timeout!(t(), non_neg_integer()) :: integer() | float() | binary() | :timeout - def recv_timeout!(pull_subscriber, timeout_us) do + @doc """ + Receive data. + + ## Examples + + iex> session = Zenohex.open!() + iex> subscriber = Zenohex.Session.declare_pull_subscriber!(session, "key/expression") + iex> Zenohex.PullSubscriber.recv_timeout!(subscriber, 1000) + :timeout + """ + @spec recv_timeout!(t(), pos_integer()) :: integer() | float() | binary() | :timeout + def recv_timeout!(pull_subscriber, timeout_us) + when is_reference(pull_subscriber) and is_integer(timeout_us) and timeout_us > 0 do Nif.pull_subscriber_recv_timeout(pull_subscriber, timeout_us) end end diff --git a/lib/zenohex/queryable.ex b/lib/zenohex/queryable.ex index 6b449ef..0bda468 100644 --- a/lib/zenohex/queryable.ex +++ b/lib/zenohex/queryable.ex @@ -1,8 +1,17 @@ defmodule Zenohex.Queryable do + @moduledoc """ + Documentation for `#{__MODULE__}`. + """ + @type t :: reference() - @type complete :: boolean() defmodule Options do + @moduledoc """ + Documentation for `#{__MODULE__}`. + """ + + @type t :: %__MODULE__{complete: complete()} + @type complete :: boolean() defstruct complete: false end end diff --git a/lib/zenohex/session.ex b/lib/zenohex/session.ex new file mode 100644 index 0000000..cc825c8 --- /dev/null +++ b/lib/zenohex/session.ex @@ -0,0 +1,128 @@ +defmodule Zenohex.Session do + @moduledoc """ + Documentation for `#{__MODULE__}`. + """ + + alias Zenohex.Nif + alias Zenohex.Publisher + alias Zenohex.Subscriber + alias Zenohex.Queryable + + @type t :: reference() + + @doc ~S""" + Create a Publisher for the given key expression. + + ## Examples + + iex> session = Zenohex.open!() + iex> Zenohex.Session.declare_publisher!(session, "key/expression") + """ + @spec declare_publisher!(t(), String.t(), Publisher.Options.t()) :: Publisher.t() + def declare_publisher!(session, key_expr, opts \\ %Publisher.Options{}) + when is_reference(session) and is_binary(key_expr) and is_struct(opts, Publisher.Options) do + Nif.declare_publisher(session, key_expr, opts) + end + + @doc ~S""" + Create a Subscriber for the given key expression. + + ## Examples + + iex> session = Zenohex.open!() + iex> Zenohex.Session.declare_subscriber!(session, "key/expression") + """ + @spec declare_subscriber!(t(), String.t(), Subscriber.Options.t()) :: Subscriber.t() + def declare_subscriber!(session, key_expr, opts \\ %Subscriber.Options{}) + when is_reference(session) and is_binary(key_expr) and is_struct(opts, Subscriber.Options) do + Nif.declare_subscriber(session, key_expr, opts) + end + + @doc ~S""" + Create a PullSubscriber for the given key expression. + + ## Examples + + iex> session = Zenohex.open!() + iex> Zenohex.Session.declare_pull_subscriber!(session, "key/expression") + """ + @spec declare_pull_subscriber!(t(), String.t(), Subscriber.Options.t()) :: Subscriber.t() + def declare_pull_subscriber!(session, key_expr, opts \\ %Subscriber.Options{}) + when is_reference(session) and is_binary(key_expr) and is_struct(opts, Subscriber.Options) do + Nif.declare_pull_subscriber(session, key_expr, opts) + end + + @doc ~S""" + Create a Quaryable for the given key expression. + + ## Examples + + iex> session = Zenohex.open!() + iex> Zenohex.Session.declare_queryable!(session, "key/expression") + """ + @spec declare_queryable!(t(), String.t(), Queryable.Options.t()) :: Queryable.t() + def declare_queryable!(session, key_expr, opts \\ %Queryable.Options{}) + when is_reference(session) and is_binary(key_expr) and is_struct(opts, Queryable.Options) do + Nif.declare_queryable(session, key_expr, opts) + end + + @doc ~S""" + Put data. + + ## Examples + + iex> session = Zenohex.open!() + iex> :ok = Zenohex.Session.put!(session, "key/expression", "value") + iex> :ok = Zenohex.Session.put!(session, "key/expression", 0) + iex> :ok = Zenohex.Session.put!(session, "key/expression", 0.0) + """ + @spec put!(t(), String.t(), binary()) :: :ok + def put!(session, key_expr, value) + when is_reference(session) and is_binary(key_expr) and is_binary(value) do + Nif.session_put_binary(session, key_expr, value) + end + + @spec put!(t(), String.t(), integer()) :: :ok + def put!(session, key_expr, value) + when is_reference(session) and is_binary(key_expr) and is_integer(value) do + Nif.session_put_integer(session, key_expr, value) + end + + @spec put!(t(), String.t(), float()) :: :ok + def put!(session, key_expr, value) + when is_reference(session) and is_binary(key_expr) and is_float(value) do + Nif.session_put_float(session, key_expr, value) + end + + @doc ~S""" + Query data from the matching queryables in the system. + + ## Examples + + iex> session = Zenohex.open!() + iex> Zenohex.Session.get_timeout!(session, "key/**", 1000) + :timeout + """ + @spec get_timeout!(t(), String.t(), pos_integer()) :: + binary() | integer() | float() | :timeout + # FIXME 返り値がリストになるケースがあるはずなので、 Nif を含めて見直し修正すること + def get_timeout!(session, selector, timeout_us) + when is_reference(session) and is_binary(selector) and is_integer(timeout_us) and + timeout_us > 0 do + Nif.session_get_timeout(session, selector, timeout_us) + end + + @doc ~S""" + Delete data. + + ## Examples + + iex> session = Zenohex.open!() + iex> Zenohex.Session.delete!(session, "key/expression") + :ok + """ + @spec delete!(t(), String.t()) :: :ok + def delete!(session, key_expr) when is_reference(session) and is_binary(key_expr) do + Nif.session_delete(session, key_expr) + end +end diff --git a/lib/zenohex/subscriber.ex b/lib/zenohex/subscriber.ex index 45aab7c..3c9fe57 100644 --- a/lib/zenohex/subscriber.ex +++ b/lib/zenohex/subscriber.ex @@ -1,15 +1,35 @@ defmodule Zenohex.Subscriber do + @moduledoc """ + Documentation for `#{__MODULE__}`. + """ + alias Zenohex.Nif - @type t :: reference() - @type reliability :: :best_effort | :reliable + @opaque t :: reference() defmodule Options do + @moduledoc """ + Documentation for `#{__MODULE__}`. + """ + + @type t :: %__MODULE__{reliability: reliability()} + @type reliability :: :best_effort | :reliable defstruct reliability: :best_effort end - @spec recv_timeout!(t(), non_neg_integer()) :: integer() | float() | binary() | :timeout - def recv_timeout!(subscriber, timeout_us) do + @doc """ + Receive data. + + ## Examples + + iex> session = Zenohex.open!() + iex> subscriber = Zenohex.Session.declare_subscriber!(session, "key/expression") + iex> Zenohex.Subscriber.recv_timeout!(subscriber, 1000) + :timeout + """ + @spec recv_timeout!(t(), pos_integer()) :: integer() | float() | binary() | :timeout + def recv_timeout!(subscriber, timeout_us) + when is_reference(subscriber) and is_integer(timeout_us) and timeout_us > 0 do Nif.subscriber_recv_timeout(subscriber, timeout_us) end end diff --git a/test/zenohex/nif_test.exs b/test/zenohex/nif_test.exs index 36b6069..908b3da 100644 --- a/test/zenohex/nif_test.exs +++ b/test/zenohex/nif_test.exs @@ -1,5 +1,5 @@ defmodule Zenohex.NifTest do - use ExUnit.Case + use ExUnit.Case, async: true alias Zenohex.Nif diff --git a/test/zenohex/publisher_test.exs b/test/zenohex/publisher_test.exs new file mode 100644 index 0000000..87eee73 --- /dev/null +++ b/test/zenohex/publisher_test.exs @@ -0,0 +1,4 @@ +defmodule Zenohex.PublisherTest do + use ExUnit.Case, async: true + doctest Zenohex.Publisher +end diff --git a/test/zenohex/pull_subscriber_test.exs b/test/zenohex/pull_subscriber_test.exs new file mode 100644 index 0000000..8272d6b --- /dev/null +++ b/test/zenohex/pull_subscriber_test.exs @@ -0,0 +1,4 @@ +defmodule Zenohex.PullSubscriberTest do + use ExUnit.Case, async: true + doctest Zenohex.PullSubscriber +end diff --git a/test/zenohex/session_test.exs b/test/zenohex/session_test.exs new file mode 100644 index 0000000..d00c612 --- /dev/null +++ b/test/zenohex/session_test.exs @@ -0,0 +1,4 @@ +defmodule Zenohex.SessionTest do + use ExUnit.Case, async: true + doctest Zenohex.Session +end diff --git a/test/zenohex/subscriber_test.exs b/test/zenohex/subscriber_test.exs new file mode 100644 index 0000000..4d055a8 --- /dev/null +++ b/test/zenohex/subscriber_test.exs @@ -0,0 +1,4 @@ +defmodule Zenohex.SubscriberTest do + use ExUnit.Case, async: true + doctest Zenohex.Subscriber +end diff --git a/test/zenohex_test.exs b/test/zenohex_test.exs index 720da75..cb93faa 100644 --- a/test/zenohex_test.exs +++ b/test/zenohex_test.exs @@ -1,4 +1,17 @@ defmodule ZenohexTest do - use ExUnit.Case + use ExUnit.Case, async: true doctest Zenohex + + test "pub/sub" do + session = Zenohex.open!() + publisher = Zenohex.Session.declare_publisher!(session, "pub/sub") + subscriber = Zenohex.Session.declare_subscriber!(session, "pub/sub") + + for i <- 1..100 do + :ok = Zenohex.Publisher.put!(publisher, "Hello Zenoh Dragon #{i}") + + assert Zenohex.Subscriber.recv_timeout!(subscriber, 1000) == + "Hello Zenoh Dragon #{i}" + end + end end