// Ion symbol tokens.
//
// Symbols are interned identifiers. Either encoding can refer to a symbol
// whose text is unknown. That absence is `None`, never an empty string; an
// unknown imported symbol retains its shared-table name and slot.
///|
/// The identity of an imported symbol with unknown text. `sid` is its
/// one-based position in the shared table, not its ID in a stream.
pub struct ImportLocation {
name : String
sid : Int32
} derive(Eq, Hash, Debug)
///|
/// A symbol token: known text, a stream-local symbol ID, and the shared-table
/// location when an imported symbol's text is unknown.
pub struct SymbolToken {
text : String?
sid : Int32?
import_location : ImportLocation?
import_version : Int32?
} derive(Eq, Hash, Debug)
///|
/// A symbol token with known text.
#as_free_fn(symbol)
#alias(new, deprecated="Use `@ion.symbol(...)` instead")
pub fn SymbolToken::SymbolToken(text : String) -> SymbolToken {
{ text: Some(text), sid: None, import_location: None, import_version: None, }
}
///|
/// A symbol token known only by its symbol ID.
pub fn SymbolToken::from_sid(sid : Int32) -> SymbolToken {
{ text: None, sid: Some(sid), import_location: None, import_version: None, }
}
///|
/// An imported symbol with unknown text. The local ID and table version are
/// retained for serialization; equivalence uses only `name` and `import_sid`.
pub fn SymbolToken::from_import(
sid : Int32,
name : String,
version : Int32,
import_sid : Int32,
) -> SymbolToken {
{
text: None,
sid: Some(sid),
import_location: Some({ name, sid: import_sid, }),
import_version: Some(version),
}
}
///|
/// Ion symbol equivalence. Known text determines identity; otherwise imported
/// symbols compare by table name and slot, and local unknown symbols equal $0.
pub fn SymbolToken::equivalent(self : SymbolToken, other : SymbolToken) -> Bool {
match (self.text, other.text) {
(Some(a), Some(b)) => a == b
(None, None) => self.import_location == other.import_location
_ => false
}
}
///|
/// The symbol's text, when known.
pub fn SymbolToken::text(self : SymbolToken) -> String? {
self.text
}
///|
/// The symbol's ID, when the context assigned one.
pub fn SymbolToken::sid(self : SymbolToken) -> Int32? {
self.sid
}
///|
/// Whether the symbol's text is known.
pub fn SymbolToken::has_text(self : SymbolToken) -> Bool {
self.text is Some(_)
}
///|
/// The symbol's text, raising [`IonError::Unsupported`] when the symbol is
/// known only by ID.
pub fn SymbolToken::require_text(self : SymbolToken) -> String raise IonError {
match self.text {
Some(text) => text
None =>
raise IonError::Unsupported(
"symbol is known only by ID (sid=\{self.sid.unwrap()}); its text is not available",
)
}
}
///|
/// The text of an Ion 1.0 system symbol ID (1..9), or `None` outside that
/// range. The system symbol table is the initial symbol table shared by every
/// Ion stream; IDs `0` and `10` and above have no text without a local symbol
/// table.
pub fn system_symbol_text(sid : Int32) -> String? {
match sid {
1 => Some("$ion")
2 => Some("$ion_1_0")
3 => Some("$ion_symbol_table")
4 => Some("name")
5 => Some("version")
6 => Some("imports")
7 => Some("symbols")
8 => Some("max_id")
9 => Some("$ion_shared_symbol_table")
_ => None
}
}