Erlang には、 ASN.1 で記述されたデータ構造のコンパイルと、エンコード/レコードをおこなうライブラリが標準で用意されています。
かつて通信機器の開発が仕事だったころにあつかっていたことを思い出しつつ、Elixir で利用する方法を記録しておきます。
とはいえ。 ASN.1 については Erlang のチュートリアルそのままで、生成した Erlang のモジュールをどのように Elixir から利用するか、というお話がすべてです。
Erlang で ASN.1 のモジュールを生成する
Erlang のマニュアルの Getting Started にしたがって、モジュールを作成します。
まず、定義ファイル People.asn
を作成します。
People DEFINITIONS AUTOMATIC TAGS ::= BEGIN Person ::= SEQUENCE { name PrintableString, location INTEGER {home(0),field(1),roving(2)}, age INTEGER OPTIONAL } END
次にこれをコンパイルしてモジュールを生成します。 Elixir から Erlang のモジュールや関数を利用するばあいは、特に引数の記述の違いに注意してください。
iex> :asn1ct.compile('People', [:per]) :ok
コンパイルに成功すると、次のファイルが生成されます。
People.asn1db People.beam People.erl People.hrl
生成されたモジュールの関数を Elixir から呼び出す
コンパイルを実行した iex から、あるいは生成されたファイルがあるディレクトリで iex を起動してそこから、次の関数を実行します。
iex> {:ok, bin} = :People.encode(:Person, {:Person, 'Some Name', :roving, 50}) {:ok, <<128, 9, 83, 111, 109, 101, 32, 78, 97, 109, 101, 1, 2, 1, 50>>}
ここで Erlang のモジュール名が People
であるため、Elixir からは :People
という名前で参照することに注意してください。
続いてエンコードした結果をデコードしてみます。
iex> :People.decode(:Person, bin) {:ok, {:Person, 'Some Name', :roving, 50}}
元のデータに復元できることが確認できました。
生成されたモジュールを Elixir のプロジェクトに含める
生成した Erlang のモジュールを mix new
コマンドで作成する Elixir のプロジェクトで利用できるようにします。
Elixir のプロジェクトでは、コンパイル対象にする Erlang のソースファイルの格納パスが src/
に設定されています。
このため作成したプロジェクト内に src/
というディレクトリを作成し、そこに先に生成された Erlang のソースファイルとヘッダファイルをコピーするだけでモジュールを利用できるようになります。
my_app/ └── src/ ├── People.erl └── People.hrl
コンパイル対象にするパスは、 mix.exs
の project/0
で :erlc_paths
を設定することで変更することができます。
くわしくは Mix.Project — Mix v1.11.3 や mix compile.erlang — Mix v1.11.3 を参照してみてください。
ファイルのコピーができたら、エンコード/デコードができることを確認してみます。
my_app $ iex -S mix iex(1)> {:ok, bin} = :People.encode(:Person, {:Person, 'Some Name', :roving, 50}) {:ok, <<128, 9, 83, 111, 109, 101, 32, 78, 97, 109, 101, 1, 2, 1, 50>>} iex(2)> {:ok, result} = :People.decode(:Person, bin) {:ok, {:Person, 'Some Name', :roving, 50}}