Struct cardano_serialization_lib::metadata::MetadataList
source · pub struct MetadataList(_);
Implementations§
source§impl MetadataList
impl MetadataList
pub fn from_bytes(bytes: Vec<u8>) -> Result<MetadataList, DeserializeError>
source§impl MetadataList
impl MetadataList
pub fn from_hex(hex_str: &str) -> Result<MetadataList, DeserializeError>
source§impl MetadataList
impl MetadataList
sourcepub fn new() -> Self
pub fn new() -> Self
Examples found in repository?
src/metadata.rs (line 424)
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
pub fn encode_arbitrary_bytes_as_metadatum(bytes: &[u8]) -> TransactionMetadatum {
let mut list = MetadataList::new();
for chunk in bytes.chunks(MD_MAX_LEN) {
// this should never fail as we are already chunking it
list.add(&TransactionMetadatum::new_bytes(chunk.to_vec()).unwrap());
}
TransactionMetadatum::new_list(&list)
}
// decodes from chunks of bytes in a list to a byte vector if that is the metadata format, otherwise returns None
#[wasm_bindgen]
pub fn decode_arbitrary_bytes_from_metadatum(
metadata: &TransactionMetadatum,
) -> Result<Vec<u8>, JsError> {
let mut bytes = Vec::new();
for elem in metadata.as_list()?.0 {
bytes.append(&mut elem.as_bytes()?);
}
Ok(bytes)
}
#[wasm_bindgen]
#[derive(Copy, Clone, Eq, PartialEq)]
// Different schema methods for mapping between JSON and the metadata CBOR.
// This conversion should match TxMetadataJsonSchema in cardano-node defined (at time of writing) here:
// https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/MetaData.hs
// but has 2 additional schemas for more or less conversionse
// Note: Byte/Strings (including keys) in any schema must be at most 64 bytes in length
pub enum MetadataJsonSchema {
// Does zero implicit conversions.
// Round-trip conversions are 100% consistent
// Treats maps DIRECTLY as maps in JSON in a natural way e.g. {"key1": 47, "key2": [0, 1]]}
// From JSON:
// * null/true/false NOT supported.
// * keys treated as strings only
// To JSON
// * Bytes, non-string keys NOT supported.
// Stricter than any TxMetadataJsonSchema in cardano-node but more natural for JSON -> Metadata
NoConversions,
// Does some implicit conversions.
// Round-trip conversions MD -> JSON -> MD is NOT consistent, but JSON -> MD -> JSON is.
// Without using bytes
// Maps are treated as an array of k-v pairs as such: [{"key1": 47}, {"key2": [0, 1]}, {"key3": "0xFFFF"}]
// From JSON:
// * null/true/false NOT supported.
// * Strings parseable as bytes (0x starting hex) or integers are converted.
// To JSON:
// * Non-string keys partially supported (bytes as 0x starting hex string, integer converted to string).
// * Bytes are converted to hex strings starting with 0x for both values and keys.
// Corresponds to TxMetadataJsonSchema's TxMetadataJsonNoSchema in cardano-node
BasicConversions,
// Supports the annotated schema presented in cardano-node with tagged values e.g. {"int": 7}, {"list": [0, 1]}
// Round-trip conversions are 100% consistent
// Maps are treated as an array of k-v pairs as such: [{"key1": {"int": 47}}, {"key2": {"list": [0, 1]}}, {"key3": {"bytes": "0xFFFF"}}]
// From JSON:
// * null/true/false NOT supported.
// * Strings parseable as bytes (hex WITHOUT 0x prefix) or integers converted.
// To JSON:
// * Non-string keys are supported. Any key parseable as JSON is encoded as metadata instead of a string
// Corresponds to TxMetadataJsonSchema's TxMetadataJsonDetailedSchema in cardano-node
DetailedSchema,
}
fn supports_tagged_values(schema: MetadataJsonSchema) -> bool {
match schema {
MetadataJsonSchema::NoConversions | MetadataJsonSchema::BasicConversions => false,
MetadataJsonSchema::DetailedSchema => true,
}
}
fn hex_string_to_bytes(hex: &str) -> Option<Vec<u8>> {
if hex.starts_with("0x") {
hex::decode(&hex[2..]).ok()
} else {
None
}
}
fn bytes_to_hex_string(bytes: &[u8]) -> String {
format!("0x{}", hex::encode(bytes))
}
// Converts JSON to Metadata according to MetadataJsonSchema
#[wasm_bindgen]
pub fn encode_json_str_to_metadatum(
json: String,
schema: MetadataJsonSchema,
) -> Result<TransactionMetadatum, JsError> {
let value = serde_json::from_str(&json).map_err(|e| JsError::from_str(&e.to_string()))?;
encode_json_value_to_metadatum(value, schema)
}
pub fn encode_json_value_to_metadatum(
value: serde_json::Value,
schema: MetadataJsonSchema,
) -> Result<TransactionMetadatum, JsError> {
use serde_json::Value;
fn encode_number(x: serde_json::Number) -> Result<TransactionMetadatum, JsError> {
if let Some(x) = x.as_u64() {
Ok(TransactionMetadatum::new_int(&Int::new(&utils::to_bignum(
x,
))))
} else if let Some(x) = x.as_i64() {
Ok(TransactionMetadatum::new_int(&Int::new_negative(
&utils::to_bignum(-x as u64),
)))
} else {
Err(JsError::from_str("floats not allowed in metadata"))
}
}
fn encode_string(
s: String,
schema: MetadataJsonSchema,
) -> Result<TransactionMetadatum, JsError> {
if schema == MetadataJsonSchema::BasicConversions {
match hex_string_to_bytes(&s) {
Some(bytes) => TransactionMetadatum::new_bytes(bytes),
None => TransactionMetadatum::new_text(s),
}
} else {
TransactionMetadatum::new_text(s)
}
}
fn encode_array(
json_arr: Vec<Value>,
schema: MetadataJsonSchema,
) -> Result<TransactionMetadatum, JsError> {
let mut arr = MetadataList::new();
for value in json_arr {
arr.add(&encode_json_value_to_metadatum(value, schema)?);
}
Ok(TransactionMetadatum::new_list(&arr))
}
pub fn len(&self) -> usize
pub fn get(&self, index: usize) -> TransactionMetadatum
sourcepub fn add(&mut self, elem: &TransactionMetadatum)
pub fn add(&mut self, elem: &TransactionMetadatum)
Examples found in repository?
src/metadata.rs (line 427)
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
pub fn encode_arbitrary_bytes_as_metadatum(bytes: &[u8]) -> TransactionMetadatum {
let mut list = MetadataList::new();
for chunk in bytes.chunks(MD_MAX_LEN) {
// this should never fail as we are already chunking it
list.add(&TransactionMetadatum::new_bytes(chunk.to_vec()).unwrap());
}
TransactionMetadatum::new_list(&list)
}
// decodes from chunks of bytes in a list to a byte vector if that is the metadata format, otherwise returns None
#[wasm_bindgen]
pub fn decode_arbitrary_bytes_from_metadatum(
metadata: &TransactionMetadatum,
) -> Result<Vec<u8>, JsError> {
let mut bytes = Vec::new();
for elem in metadata.as_list()?.0 {
bytes.append(&mut elem.as_bytes()?);
}
Ok(bytes)
}
#[wasm_bindgen]
#[derive(Copy, Clone, Eq, PartialEq)]
// Different schema methods for mapping between JSON and the metadata CBOR.
// This conversion should match TxMetadataJsonSchema in cardano-node defined (at time of writing) here:
// https://github.com/input-output-hk/cardano-node/blob/master/cardano-api/src/Cardano/Api/MetaData.hs
// but has 2 additional schemas for more or less conversionse
// Note: Byte/Strings (including keys) in any schema must be at most 64 bytes in length
pub enum MetadataJsonSchema {
// Does zero implicit conversions.
// Round-trip conversions are 100% consistent
// Treats maps DIRECTLY as maps in JSON in a natural way e.g. {"key1": 47, "key2": [0, 1]]}
// From JSON:
// * null/true/false NOT supported.
// * keys treated as strings only
// To JSON
// * Bytes, non-string keys NOT supported.
// Stricter than any TxMetadataJsonSchema in cardano-node but more natural for JSON -> Metadata
NoConversions,
// Does some implicit conversions.
// Round-trip conversions MD -> JSON -> MD is NOT consistent, but JSON -> MD -> JSON is.
// Without using bytes
// Maps are treated as an array of k-v pairs as such: [{"key1": 47}, {"key2": [0, 1]}, {"key3": "0xFFFF"}]
// From JSON:
// * null/true/false NOT supported.
// * Strings parseable as bytes (0x starting hex) or integers are converted.
// To JSON:
// * Non-string keys partially supported (bytes as 0x starting hex string, integer converted to string).
// * Bytes are converted to hex strings starting with 0x for both values and keys.
// Corresponds to TxMetadataJsonSchema's TxMetadataJsonNoSchema in cardano-node
BasicConversions,
// Supports the annotated schema presented in cardano-node with tagged values e.g. {"int": 7}, {"list": [0, 1]}
// Round-trip conversions are 100% consistent
// Maps are treated as an array of k-v pairs as such: [{"key1": {"int": 47}}, {"key2": {"list": [0, 1]}}, {"key3": {"bytes": "0xFFFF"}}]
// From JSON:
// * null/true/false NOT supported.
// * Strings parseable as bytes (hex WITHOUT 0x prefix) or integers converted.
// To JSON:
// * Non-string keys are supported. Any key parseable as JSON is encoded as metadata instead of a string
// Corresponds to TxMetadataJsonSchema's TxMetadataJsonDetailedSchema in cardano-node
DetailedSchema,
}
fn supports_tagged_values(schema: MetadataJsonSchema) -> bool {
match schema {
MetadataJsonSchema::NoConversions | MetadataJsonSchema::BasicConversions => false,
MetadataJsonSchema::DetailedSchema => true,
}
}
fn hex_string_to_bytes(hex: &str) -> Option<Vec<u8>> {
if hex.starts_with("0x") {
hex::decode(&hex[2..]).ok()
} else {
None
}
}
fn bytes_to_hex_string(bytes: &[u8]) -> String {
format!("0x{}", hex::encode(bytes))
}
// Converts JSON to Metadata according to MetadataJsonSchema
#[wasm_bindgen]
pub fn encode_json_str_to_metadatum(
json: String,
schema: MetadataJsonSchema,
) -> Result<TransactionMetadatum, JsError> {
let value = serde_json::from_str(&json).map_err(|e| JsError::from_str(&e.to_string()))?;
encode_json_value_to_metadatum(value, schema)
}
pub fn encode_json_value_to_metadatum(
value: serde_json::Value,
schema: MetadataJsonSchema,
) -> Result<TransactionMetadatum, JsError> {
use serde_json::Value;
fn encode_number(x: serde_json::Number) -> Result<TransactionMetadatum, JsError> {
if let Some(x) = x.as_u64() {
Ok(TransactionMetadatum::new_int(&Int::new(&utils::to_bignum(
x,
))))
} else if let Some(x) = x.as_i64() {
Ok(TransactionMetadatum::new_int(&Int::new_negative(
&utils::to_bignum(-x as u64),
)))
} else {
Err(JsError::from_str("floats not allowed in metadata"))
}
}
fn encode_string(
s: String,
schema: MetadataJsonSchema,
) -> Result<TransactionMetadatum, JsError> {
if schema == MetadataJsonSchema::BasicConversions {
match hex_string_to_bytes(&s) {
Some(bytes) => TransactionMetadatum::new_bytes(bytes),
None => TransactionMetadatum::new_text(s),
}
} else {
TransactionMetadatum::new_text(s)
}
}
fn encode_array(
json_arr: Vec<Value>,
schema: MetadataJsonSchema,
) -> Result<TransactionMetadatum, JsError> {
let mut arr = MetadataList::new();
for value in json_arr {
arr.add(&encode_json_value_to_metadatum(value, schema)?);
}
Ok(TransactionMetadatum::new_list(&arr))
}
Trait Implementations§
source§impl Clone for MetadataList
impl Clone for MetadataList
source§fn clone(&self) -> MetadataList
fn clone(&self) -> MetadataList
Returns a copy of the value. Read more
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source
. Read moresource§impl Debug for MetadataList
impl Debug for MetadataList
source§impl Deserialize for MetadataList
impl Deserialize for MetadataList
fn deserialize<R: BufRead + Seek>(
raw: &mut Deserializer<R>
) -> Result<Self, DeserializeError>
source§impl Hash for MetadataList
impl Hash for MetadataList
source§impl Ord for MetadataList
impl Ord for MetadataList
source§fn cmp(&self, other: &MetadataList) -> Ordering
fn cmp(&self, other: &MetadataList) -> Ordering
1.21.0 · source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Compares and returns the maximum of two values. Read more
source§impl PartialEq<MetadataList> for MetadataList
impl PartialEq<MetadataList> for MetadataList
source§fn eq(&self, other: &MetadataList) -> bool
fn eq(&self, other: &MetadataList) -> bool
This method tests for
self
and other
values to be equal, and is used
by ==
.source§impl PartialOrd<MetadataList> for MetadataList
impl PartialOrd<MetadataList> for MetadataList
source§fn partial_cmp(&self, other: &MetadataList) -> Option<Ordering>
fn partial_cmp(&self, other: &MetadataList) -> Option<Ordering>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
This method tests less than or equal to (for
self
and other
) and is used by the <=
operator. Read more