Welcome to yamlcast’s documentation!

yamlcastはYAMLデータを読み込んで、指定した型に変換するためのライブラリです。 YAMLは設定ファイルの記述などに広く使われていますが、各設定項目が期待した型になっているかどうかを網羅的にチェックするのは面倒です。 yamlcastとpficommonを利用すると、指定した構造体への変換と型チェックがほぼ自動で行われます。

インストール方法

動作環境

インストールには、以下のパッケージが必要です。

また、ソースからビルドするためには、以下のツールが必要になります。

  • Python
  • g++
  • pkg-config

ビルド方法

ビルドシステムとしてwafを利用しています。 同梱されているので、Pythonさえあればビルドすることができます。

$ ./waf configure
$ ./waf
$ sudo ./waf install

インストール先をかえるときは、configure時に指定して下さい。

$ ./waf configure --prefix=$HOME

ライセンス

yamlcastはMITライセンスで配布されています。

使い方

yamlcastはC++から使われます。 利用したいソースファイルから yamlcast.hpp をインクルードして下さい。

#include <yamlcast.hpp>

簡単な使い方

はじめに、 yamlcast::document を用意する必要があります。 このオブジェクトは、単一のYAMLドキュメントを示します。 実体は、libyamlの薄いラッパーです。 文字列をパースするときは、 yamlcast::document::parse_string を使って下さい。

std::string str = "...";
yamlcast::document::ptr doc = yamlcast::document::parse_string(str);

ファイルをパースするときは、 yamlcast::document::parse_file を使って下さい。

yamlcast::document::ptr doc = yamlcast::document::parse_file("/path/to/file");

準備が出来ました。 yamlcast::yaml_cast() を呼び出しましょう。 読み込んだYAML文書を、任意の型に変換します。

std::map<std::string, int> m
  = yamlcast::yaml_cast<std::map<std::string, int> >(*doc);

YAMLの各ノードは、値を示すスカラー(scalar)と、配列を示すシーケンス(sequence)、ハッシュを示すマッピング(mapping)があります。 個別のデータ型はスカラーから、 std::vector にはシーケンスから、 std::map にはマッピングから変換できます。

ユーザー定義型

YAMLのマッピングから、ユーザー定義の型に変換することもできます。 この場合、pficommonのシリアライザを使います。 pficommonのシリアライザは、 serialize という名前のtemplateメンバ関数を作ることで利用できます。 引数に渡された参照に対して、 operator & で、データをシリアライズできます。 このとき、 MEMBER マクロでメンバ関数をくくって下さい。

#include <pficommon/data/serialization.h>

struct User {
  int age;
  std::string name;

  template <typename Ar>
  void serialize(Ar& ar) {
    ar & MEMBER(age) & MEMBER(name);
  }
};

// ...

User user = yamlcast::yaml_cast<User>(*doc);

エラー処理

yamlcastのエラーは大きく分けて2つあります。 1つは、YAML文書の読み込みの失敗で、これは正しくないYAML文書が与えられた時に発生します。 もう1つは、型変換時の不整合で、与えたYAML文書が期待した型になっていない時に発生します。

YAML文書のチェックはパース時に行われます。 以下の文字列は [ が閉じていませんから、正しいYAML文書として読み込めません。

yamlcast::document::parse_string("[1,2");

このとき、 yamlcast::yaml_parse_exception が発生します。

型情報のチェックはキャストするときに行われます。 型の不整合は、3種類あります。

YAML文書上での型と、キャスト先の型が一致しない時は、 yamlcast::yaml_bad_cast が発生します。

yamlcast::document::ptr d = yamlcast::document::parse_string("{\"name\": \"taro\"}");
std::vector<std::string> xs = yamalcast::yaml_cast<std::vector<std::string> >(*d);

上の例は、 vector にキャストしたかったため、シーケンスを期待していましたが、マッピングが与えられたので、エラーとなります。

YAML文書上では、文字列と数値は、いずれもスカラーとして区別されません。 スカラーの値を対象の型に変換するのに失敗すると、 yamlcast::yaml_invalid_scalar が発生します。

yamlcast::document::ptr d = yamlcast::document::parse_string("[1, \"hello\"]");
std::vector<int> xs = yamalcast::yaml_cast<std::vector<int> >(*d);

上の例は、 “hello” という文字列を int に変換しようとしたため、エラーが発生します。

ユーザー定義型は、YAML文書上ではマッピングを利用します。 想定したフィールドが存在しない時は、 yamlcast::yaml_not_found が発生します。

yamlcast::document::ptr d = yamlcast::document::parse_string("{\"age\": 20}");
User user = yamalcast::yaml_cast<User>(*d);

上の例は、 User 中の name フィールドが、マッピング中に存在しないためエラーが発生します。

API

yamlcastのAPIです。

YAML文書

yamlcastはlibyamlの薄いラッパーを提供します。 document は読み込まれたYAMLドキュメントを、 node はYAMLドキュメント中の各ノードを示すクラスです。

class document

読み込んだYAMLドキュメントを示します。 中身は、libyamlのdocument_t型へのポインタです。

type ptr

yamlcast::document へのshared_ptrの別名です。

static ptr parse_string(const std::string &str)

文字列をパースして、読み込まれたドキュメントを返します。

パラメタ str:パース対象の文字列を渡します。
戻り値:パースした結果を yamlcast::document へのポインタで返します。
例外 yamlcast::yaml_parse_exception:
 パースに失敗した場合に発生します。
static document::ptr parse_file(const std::string &path)
static document::ptr parse_file(FILE *file)

フィアルを読み込んでパース市、読み込まれたドキュメントを返します。

パラメタ str:パース対象ファイルへのパスを渡します。
戻り値:パースした結果を yamlcast::document へのポインタで返します。
例外 yamlcast::yaml_parse_exception:
 パースに失敗した場合に発生します。
node get_root() const

ルートノードを取得します。

class node

yamlcast::document 中のノードを示します。 ノードには、スカラー、シーケンス、マッピングの3種類のタイプが有ります。

const document &get_document() const

このノードが所属するYAML文書への参照を返します。

yaml_node_type_t type() const

このノードの種類を示します。

scalar as_scalar() const

このノードをスカラーとして扱います。 ノードがスカラーでない時は例外が発生します。 ノードのタイプは、 yamlcast::node::type() で確認できます。

例外 yamlcast::yaml_bad_cast:
 ノードがスカラーでない時に発生します。
sequence as_sequence() const

このノードをシーケンスとして扱います。 ノードがシーケンスでない時は例外が発生します。 ノードのタイプは、 yamlcast::node::type() で確認できます。

例外 yamlcast::yaml_bad_cast:
 ノードがスカラーでない時に発生します。
mapping as_mapping() const

このノードをマッピングとして扱います。 ノードがマッピングでない時は例外が発生します。 ノードのタイプは、 yamlcast::node::type() で確認できます。

例外 yamlcast::yaml_bad_cast:
 ノードがスカラーでない時に発生します。
const yaml_mark_t &start_mark() const

このノードの入力データ中での開始位置を取得します。

const yaml_mark_t &end_mark() const

このノードの入力データ中での終了位置を取得します。

class scalar

スカラーのノードを示します。 スカラーは、値を内部では文字列として持っています。 数値やブール値へは、値を読んで変換をする必要があります。

bool operator==(const char *str) const
bool operator==(const std::string &str) const

スカラーの値が、与えられた文字列と一致するか調べます。

size_t length() const

スカラーの値の文字列の長さを取得します。

const char *value() const

スカラーの値の文字列へのポインタを取得します。

std::string str() const

スカラーの値の文字列を、 std::string として取得します。

class sequence

シーケンスのノードを示します。 シーケンスは内部に複数のノードを保持しています。

const_iterator begin() const

シーケンスの最初の要素へのイテレーターを取得します。

const_iterator end() const

シーケンスの最後の要素の次へのイテレーターを取得します。

std::size_t size() const

シーケンス中のノードの数を取得します。

node operator[](const std::size_t i) const

i 番目のノードを取得します。

class mapping

マッピングのノードを示します。 マッピングは内部にキーと値のノードを保持します。

const_iterator begin() const

マッピングの最初の要素へのイテレーターを取得します。

const_iterator end() const

マッピングの最後の要素の次へのイテレーターを取得します。

const_iterator find(const std::string &key) const

指定された文字列をキーとして持つ要素を探して、そのイテレーターを返します。 見つからなかった時は、 end() の値を返します。

std::size_t count(const std::string &key) const

指定された文字列をキーとして持つ要素の数を返します。

キャスト

YAML文書を読み込んだら、 yamlcast::yaml_cast() 関数を呼び出して変換を行います。

T yaml_cast<T>(const document &yaml)

YAML文書を与えられて型Tとしてパースします。 パースの規則は、型Tに依存します。

ユーザー定義型など、下記の型以外への変換は、pficommonのシリアライザにしたがって、 serialize メンバ関数を呼び出します。 serializa 関数内では、 MEMBER マクロか、 NAMED_MEMBER マクロを使って、変換したいフィールドを指定して下さい。 与えられたYAMLがマッピングの時に、指定されたフィールドを対象のメンバ変数に変換します。

例外:
  • yaml_bad_cast – 対象がマッピングではない場合に発生します。
  • yaml_not_found – 指定されたフィールドが見つからなかった時に発生します。
bool yaml_cast<bool>(const document &yaml)

YAMLをブール値に変換します。

戻り値:

文字列”true”の場合はtrueに、”false”の場合はfalseを返します。

例外:
  • yaml_bad_cast – 対象がスカラーではない場合に発生します。
  • yaml_invalid_scalar – スカラーの値だが、”true”でも”false”でもない場合に発生します。
bool yaml_cast<int8_t>(const document &yaml)
bool yaml_cast<int16_t>(const document &yaml)
bool yaml_cast<int32_t>(const document &yaml)
bool yaml_cast<int64_t>(const document &yaml)
bool yaml_cast<uint8_t>(const document &yaml)
bool yaml_cast<uint16_t>(const document &yaml)
bool yaml_cast<uint32_t>(const document &yaml)
bool yaml_cast<uint64_t>(const document &yaml)

YAMLを整数に変換します。

戻り値:

文字列を整数に変換した結果を返します。

例外:
  • yaml_bad_cast – 対象がスカラーではない場合に発生します。
  • yaml_invalid_scalar – スカラーの値が整数でないときや、範囲外の値のときに発生します。
bool yaml_cast<float>(const document &yaml)
bool yaml_cast<double>(const document &yaml)

YAMLを浮動小数点数に変換します。

戻り値:

文字列を浮動小数点数に変換した値を返します。

例外:
  • yaml_bad_cast – 対象がスカラーではない場合に発生します。
  • yaml_invalid_scalar – スカラーの値が浮動小数点数でないときに発生します。
std::vector<T> yaml_cast<std::vector<T>>(const document &yaml)

YAMLを配列に変換します。 対象のノードがシーケンスの場合に、再帰的にシーケンス中のノードを T 型に変換します。

戻り値:変換された配列を返します。
例外 yaml_bad_cast:
 対象がシーケンスではない場合や、再帰的な要素の変換に失敗した時に発生します。
std::map<K, V> yaml_cast<std::map<K, V>>(const document &yaml)

YAMLをマップに変換します。 対象のノードがマッピングの場合に、再帰的にマッピング中のキーと値のノードを K, V 型に変換します。

戻り値:変換されたマップを返します。
例外 yaml_bad_cast:
 対象がマッピングではない場合や、再帰的な要素の変換に失敗した時に発生します。

例外

YAML文書のパースや、YAML文書からの変換が失敗した場合、戻り値ではなくて例外で失敗を通知します。 ここでは、yamlcastが生成する例外を解説します。

class yaml_exception : public std::exception

yamlcastの返す全ての例外のベースクラスとなります。

class yaml_parse_exception : public yaml_exception

YAMLの構文解析に失敗した時に発生する例外です。

const yaml_mark_t &get_problem_mark() const

エラーが起こった場所を取得します。

class yaml_cast_exception : public yaml_exception

読み込んだYAMLデータから型変換に失敗するときに発生する例外です。

const yaml_mark_t &get_start_mark() const

エラーの原因となったYAMLのノードの開始位置を取得します。

const yaml_mark_t &get_end_mark() const

エラーの原因となったYAMLのノードの終了位置を取得します。

class yaml_bad_cast : public yaml_cast_exception

指定した型への変換に失敗した時に発生する例外です。

yaml_node_type_t get_expect() const

期待したYAMLのタイプを取得します。

yaml_node_type_t get_actual() const

実際のYAMLのタイプを取得します。

class yaml_invalid_scalar : public yaml_cast_exception

YAML文書中のスカラーを、指定した型に変換するのに失敗した時に発生する例外です。

const std::type_info &get_type() const

変換に失敗したデータ型を取得します。

class yaml_not_found : public yaml_cast_exception

ユーザー定義型へ変換するときに、期待したフィールドが見つからなかった沖に発生する例外です。

const std::string &get_key() const

見つからなかったフィールド名を取得します。

libyaml

yamlcastの一部のインターフェースは、libyamlのデータ型をそのまま使っています。 直接利用することの有るlibyaml中でのデータ型について解説します。

type yaml_node_type_t

YAMLのノードタイプを示す型です。

type yaml_mark_t

読み込んだファイルの位置を示す型です。 行数やカラム数を保持します。