Module abi_stable::type_layout::tagging [−][src]
Expand description
Tag is a dynamically typed data structure used to encode extra properties about a type in its layout constant.
Comparison semantics
Tags don’t use strict equality when doing layout checking , here is an exhaustive list on what is considered compatible for each variant in the interface:
-
Null: A Tag which is compatible with any other one. Note that Nulls are stripped from arrays,set,and map keys.
-
Integers/bools/strings: They must be strictly equal.
-
Arrays: They must have the same length, and have elements that compare equal.
-
Sets/Maps: The set/map in the interface must be a subset of the implementation,
Examples
Declaring a unit type with a tag.
use abi_stable::{tag,StableAbi};
#[repr(C)]
#[derive(StableAbi)]
#[sabi( tag = r##" tag!("WAT") "## )]
struct UnitType;
Emulating const generics for strings
This emulates a const NAME:&'static str
parameter,
which is checked as being the same between the interface and implementation.
use abi_stable::{tag,StableAbi,marker_type::UnsafeIgnoredType};
trait Name{
const NAME:&'static str;
}
///
/// The layout of `StringParameterized<S>` is determined by `<S as Name>::NAME`,
/// allowing the interface crate to have a different `S`
/// type parameter than the implementation crate,
/// so long as they have the same associated `&'static str`.
///
/// StringParameterized<Foo> has the "same" layout as StringParameterized<Bar>.
///
/// StringParameterized<Foo> has a "different" layout to StringParameterized<Boor>.
///
#[repr(C)]
#[derive(StableAbi)]
#[sabi(
bound="S:Name",
tag = r##" tag!( S::NAME ) "## ,
)]
struct StringParameterized<S>{
_marker:UnsafeIgnoredType<S>
}
#[repr(C)]
#[derive(StableAbi)]
struct Foo;
impl Name for Foo{
const NAME:&'static str="Hello, World!";
}
#[repr(C)]
#[derive(StableAbi)]
struct Bar;
impl Name for Bar{
const NAME:&'static str="Hello, Helloooooo!";
}
#[repr(C)]
#[derive(StableAbi)]
struct Boor;
impl Name for Boor{
const NAME:&'static str="This is a different string!";
}
Declaring each variant.
use abi_stable::{
rslice,tag,
type_layout::Tag,
};
const NULL:Tag=Tag::null();
const BOOL_MACRO:Tag=tag!( false );
const BOOL_FN :Tag=Tag::bool_(false);
const INT_MACRO_0:Tag=tag!( 100 );
const INT_FN_0 :Tag=Tag::int(100);
const INT_MACRO_1:Tag=tag!( -100 );
const INT_FN_1 :Tag=Tag::int(-100);
// This can only be declared using the function for now.
const UINT:Tag=Tag::uint(100);
const STR_0_MACRO:Tag=tag!("Hello,World!");
const STR_0_FN:Tag=Tag::str("Hello,World!");
const ARR_0_MACRO:Tag=tag![[ 0,1,2,3 ]];
const ARR_0_FN:Tag=Tag::arr(rslice![
Tag::int(0),
Tag::int(1),
Tag::int(2),
Tag::int(3),
]);
const SET_0_MACRO:Tag=tag!{{ 0,1,2,3 }};
const SET_0_FN:Tag=Tag::set(rslice![
Tag::int(0),
Tag::int(1),
Tag::int(2),
Tag::int(3),
]);
const MAP_0_MACRO:Tag=tag!{{
0=>"a",
1=>"b",
2=>false,
3=>100,
}};
const MAP_0_FN:Tag=Tag::map(rslice![
Tag::kv( Tag::int(0), Tag::str("a")),
Tag::kv( Tag::int(1), Tag::str("b")),
Tag::kv( Tag::int(2), Tag::bool_(false)),
Tag::kv( Tag::int(3), Tag::int(100)),
]);
Creating a complex data structure.
use abi_stable::{
tag,
type_layout::Tag,
};
const TAG:Tag=tag!{{
// This must match exactly,
// adding required traits on the interface or the implementation
// would be a breaking change.
"required"=>tag![[
"Copy",
]],
"requires at least"=>tag!{{
"Debug",
"Display",
}},
"maps"=>tag!{{
0=>"Zero",
1=>"One",
}}
}};
Structs
A tag that can be checked for compatibility with another tag.
Used to convert many types to Tag
.
A key-value pair,used when constructing a map.
Tag is a dynamically typed data structure used to encode extra properties about a type in its layout constant.
The error produced when checking CheckableTag
s.
Enums
The possible variants of CheckableTag.
The primitive types of a variant,which do not contain other nested tags.
All the Tag variants.