#![allow(
    clippy::excessive_precision,
    clippy::float_cmp,
    clippy::needless_pass_by_value,
    clippy::needless_raw_string_hashes,
    clippy::too_many_lines
)]

// Exact fixture provenance at LibreMetaverse 2aa70bb68513b39795da5d13c88f31b86e85a3ba:
// BinaryLLSDTests.cs  5aca4b55fa1ac8915598db4c24346af04ea317a0cdefa1cf0a654d910e604cec
// NotationLLSDTests.cs 3518b2b546d34bde6ef4cf289010a711ae1b637ba17fd62de854d3fd6f2ec5f1
// ProtobufTests.cs    393ab846229a66f47333c8628f809d5ae2c7183ae77866c6e188fcd845c02362
// XmlLLSDTests.cs     9949af89d931f0287a34e98275ef59177f9de6bf015b67f9de5a41669168c9bd
// TypeTests.cs        ac07dba8b9db3a4a79143f27024e6074c84b7f3dbbe6179fa784c0f4184b1b0a

use libremetaverse_compat_tests::{assert_bytes_eq, assert_close};
use libremetaverse_structured_data::{OSD, OSDParser, OSDType};
use libremetaverse_types::compat::{StringReader, Uri, Utf16CodeUnit};
use libremetaverse_types::{UUID, Utils};
use std::io::{Cursor, Read, Write};
use std::sync::{Arc, Mutex};
use std::time::{Duration, SystemTime, UNIX_EPOCH};

enum Expected {
    Undef,
    Bool(bool),
    Integer(i32),
    Real(f64),
    String(&'static str),
    Uuid(&'static str),
    UuidValue(&'static str),
    Date(SystemTime),
    Uri(&'static str),
    UriString(&'static str),
    Binary(&'static [u8]),
    Array(Vec<Expected>),
    Map(Vec<(&'static str, Expected)>),
}

fn utc(seconds: u64, millis: u64) -> SystemTime {
    UNIX_EPOCH + Duration::from_secs(seconds) + Duration::from_millis(millis)
}

fn make(expected: &Expected) -> OSD {
    match expected {
        Expected::Undef => OSD::new().expect("OSD constructor"),
        Expected::Bool(value) => OSD::from_boolean(*value).expect("OSD FromBoolean"),
        Expected::Integer(value) => {
            OSD::from_integer_with_int32(*value).expect("OSD FromInteger(Int32)")
        }
        Expected::Real(value) => OSD::from_real_with_double(*value).expect("OSD FromReal(Double)"),
        Expected::String(value) => OSD::from_string((*value).into()).expect("OSD FromString"),
        Expected::Uuid(value) | Expected::UuidValue(value) => {
            OSD::from_uuid(UUID::new_with_string((*value).into()).expect("UUID string constructor"))
                .expect("OSD FromUUID")
        }
        Expected::Date(value) => OSD::from_date(*value).expect("OSD FromDate"),
        Expected::Uri(value) | Expected::UriString(value) => {
            OSD::from_uri(Uri((*value).into())).expect("OSD FromUri")
        }
        Expected::Binary(value) => OSD::from_binary(value.to_vec()).expect("OSD FromBinary"),
        Expected::Array(values) => OSD::Array(values.iter().map(make).collect()),
        Expected::Map(values) => OSD::Map(
            values
                .iter()
                .map(|(key, value)| ((*key).to_owned(), make(value)))
                .collect(),
        ),
    }
}

fn assert_osd(actual: OSD, expected: &Expected) {
    let expected_type = match expected {
        Expected::Undef => OSDType::Unknown,
        Expected::Bool(_) => OSDType::Boolean,
        Expected::Integer(_) => OSDType::Integer,
        Expected::Real(_) => OSDType::Real,
        Expected::String(_) => OSDType::String,
        Expected::Uuid(_) | Expected::UuidValue(_) => OSDType::UUID,
        Expected::Date(_) => OSDType::Date,
        Expected::Uri(_) | Expected::UriString(_) => OSDType::URI,
        Expected::Binary(_) => OSDType::Binary,
        Expected::Array(_) => OSDType::Array,
        Expected::Map(_) => OSDType::Map,
    };
    assert_eq!(actual.type_(), expected_type);
    match (actual, expected) {
        (actual, Expected::Undef) => assert_eq!(actual.type_(), OSDType::Unknown),
        (actual, Expected::Bool(expected)) => {
            assert_eq!(actual.as_boolean().expect("OSD AsBoolean"), *expected);
        }
        (actual, Expected::Integer(expected)) => {
            assert_eq!(actual.as_integer().expect("OSD AsInteger"), *expected);
        }
        (actual, Expected::Real(expected)) if expected.is_nan() => {
            assert!(actual.as_real().expect("OSD AsReal").is_nan());
        }
        (actual, Expected::Real(expected)) => {
            assert_eq!(actual.as_real().expect("OSD AsReal"), *expected);
        }
        (
            actual,
            Expected::String(expected) | Expected::Uuid(expected) | Expected::UriString(expected),
        ) => {
            assert_eq!(actual.as_string().expect("OSD AsString"), *expected);
        }
        (actual, Expected::UuidValue(expected)) => {
            let actual = actual.as_uuid().expect("OSD AsUUID");
            let expected =
                UUID::new_with_string((*expected).into()).expect("expected UUID constructor");
            assert!(actual.equals_with_uuid(expected));
        }
        (actual, Expected::Date(expected)) => {
            assert_eq!(actual.as_date().expect("OSD AsDate"), *expected);
        }
        (actual, Expected::Uri(expected)) => {
            let uri = actual.as_uri().expect("OSD AsUri").expect("URI value");
            assert_eq!(uri.0, *expected);
        }
        (actual, Expected::Binary(expected)) => {
            assert_bytes_eq(&actual.as_binary().expect("OSD AsBinary"), expected);
        }
        (OSD::Array(actual), Expected::Array(expected)) => {
            assert_eq!(actual.len(), expected.len());
            for (actual, expected) in actual.into_iter().zip(expected) {
                assert_osd(actual, expected);
            }
        }
        (OSD::Map(mut actual), Expected::Map(expected)) => {
            assert_eq!(actual.len(), expected.len());
            for (key, expected) in expected {
                assert_osd(actual.remove(*key).expect("expected map key"), expected);
            }
        }
        _ => panic!("OSD variant did not match its reported type"),
    }
}

fn binary(value: &[u8]) -> Vec<u8> {
    [b"<?llsd/binary?>\n".as_slice(), value].concat()
}

#[derive(Clone)]
struct SharedCursor(Arc<Mutex<Cursor<Vec<u8>>>>);

impl SharedCursor {
    fn new(bytes: &[u8]) -> Self {
        Self(Arc::new(Mutex::new(Cursor::new(bytes.to_vec()))))
    }

    fn position(&self) -> u64 {
        self.0.lock().expect("cursor lock").position()
    }

    fn set_position(&self, position: u64) {
        self.0.lock().expect("cursor lock").set_position(position);
    }
}

impl Read for SharedCursor {
    fn read(&mut self, buffer: &mut [u8]) -> std::io::Result<usize> {
        self.0.lock().expect("cursor lock").read(buffer)
    }
}

impl Write for SharedCursor {
    fn write(&mut self, buffer: &[u8]) -> std::io::Result<usize> {
        self.0.lock().expect("cursor lock").write(buffer)
    }

    fn flush(&mut self) -> std::io::Result<()> {
        self.0.lock().expect("cursor lock").flush()
    }
}

const BINARY_STRING_CONTENT: &[u8] = b"testing a simple binary conversion for this string\n\r";
const BINARY_NESTED_VALUE: &[u8] = &[
    0x5b, 0, 0, 0, 3, 0x7b, 0, 0, 0, 2, 0x6b, 0, 0, 0, 4, b't', b'e', b's', b't', 0x73, 0, 0, 0, 4,
    b'w', b'h', b'a', b't', 0x6b, 0, 0, 0, 4, b't', b'0', b's', b't', 0x5b, 0, 0, 0, 2, 0x69, 0, 0,
    0, 1, 0x69, 0, 0, 0, 2, 0x5d, 0x7d, 0x69, 0, 0, 0, 0x7c, 0x69, 0, 0, 3, 0xdb, 0x5d,
];

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.HelperFunctions::test 2e76ce199c2d56677831b18d049db19098e36a3a6c648785450e30b457833b03 translated
#[test]
fn binary_helper_functions() {
    let stream =
        SharedCursor::new(b"this is a teststring so that we can find something from the beginning");
    assert!(OSDParser::find_string(Box::new(stream.clone()), "this".into()).expect("FindString"));
    assert_eq!(stream.position(), 4);
    stream.set_position(10);
    assert!(
        OSDParser::find_string(Box::new(stream.clone()), "teststring".into()).expect("FindString")
    );
    assert_eq!(stream.position(), 20);
    stream.set_position(25);
    assert!(
        !OSDParser::find_string(Box::new(stream.clone()), "notfound".into()).expect("FindString")
    );
    assert_eq!(stream.position(), 25);
    stream.set_position(60);
    assert!(
        !OSDParser::find_string(Box::new(stream.clone()), "beginningAndMore".into())
            .expect("FindString")
    );
    assert_eq!(stream.position(), 60);

    for (bytes, start, expected) in [
        (b"   \t\t\n\rtest".as_slice(), 0, 7),
        (b"test \t\t\n\rtest".as_slice(), 4, 9),
        (b"testtesttest".as_slice(), 0, 0),
    ] {
        let stream = SharedCursor::new(bytes);
        stream.set_position(start);
        OSDParser::skip_white_space(Box::new(stream.clone())).expect("SkipWhiteSpace");
        assert_eq!(stream.position(), expected);
    }
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeUndef::test 9bd23543dfef3ad9ac7df278ad70f4d115ee429aea1575ca4f7ae81ac42d6d5c translated
#[test]
fn binary_deserialize_undef() {
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(binary(&[0x21]))
        .expect("OSDParser DeserializeLLSDBinary");
    assert_osd(actual, &Expected::Undef);
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeUndef::test e40b444801b08d08b1df4817855f8965d44302c77bc544bc06745a5bd41af7e3 translated
#[test]
fn binary_serialize_undef() {
    let actual = OSDParser::serialize_llsd_binary_with_osd(make(&Expected::Undef))
        .expect("OSDParser SerializeLLSDBinary");
    assert_bytes_eq(&actual, &binary(&[0x21]));
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeBool::test 531ee8ef1cb630baf895ae6509e018f71f1866f1d57e9d97efd7869ecaef39c7 translated
#[test]
fn binary_deserialize_bool() {
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(binary(&[0x31]))
        .expect("OSDParser DeserializeLLSDBinary true");
    assert_osd(actual, &Expected::Bool(true));
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(binary(&[0x30]))
        .expect("OSDParser DeserializeLLSDBinary false");
    assert_osd(actual, &Expected::Bool(false));
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeBool::test 854f22dcb119617ef83528c9b9879c8924fdae7830edff4031aef8826a1bba63 translated
#[test]
fn binary_serialize_bool() {
    let actual = OSDParser::serialize_llsd_binary_with_osd(make(&Expected::Bool(true)))
        .expect("OSDParser SerializeLLSDBinary true");
    assert_bytes_eq(&actual, &binary(&[0x31]));
    let actual = OSDParser::serialize_llsd_binary_with_osd(make(&Expected::Bool(false)))
        .expect("OSDParser SerializeLLSDBinary false");
    assert_bytes_eq(&actual, &binary(&[0x30]));
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeInteger::test 09feba2ef1a3357273b677ee8ee35c72528e68ca0fe92b6a0b1b5491025147d1 translated
#[test]
fn binary_deserialize_integer() {
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(binary(&[0x69, 0, 0, 0, 0]))
        .expect("OSDParser DeserializeLLSDBinary zero integer");
    assert_osd(actual, &Expected::Integer(0));
    let actual =
        OSDParser::deserialize_llsd_binary_with_bytes(binary(&[0x69, 0, 0x12, 0xd7, 0x9b]))
            .expect("OSDParser DeserializeLLSDBinary integer");
    assert_osd(actual, &Expected::Integer(1_234_843));
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeInteger::test 789d62f170c3e92d9dad187484c0e4c6fd554f6e0b025f08086878551ea9119c translated
#[test]
fn binary_serialize_integer() {
    for (value, fixture) in [
        (0, [0x69, 0, 0, 0, 0]),
        (1_234_843, [0x69, 0, 0x12, 0xd7, 0x9b]),
    ] {
        let actual = OSDParser::serialize_llsd_binary_with_osd(make(&Expected::Integer(value)))
            .expect("OSDParser SerializeLLSDBinary integer");
        assert_bytes_eq(&actual, &binary(&fixture));
        let actual = OSDParser::serialize_llsd_binary_with_osd_boolean(
            make(&Expected::Integer(value)),
            false,
        )
        .expect("OSDParser SerializeLLSDBinary integer without header");
        assert_bytes_eq(&actual, &fixture);
    }
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeReal::test 1acda53f2049f062f359a4dd3271796a8051a37a1dff02150794107fc743c934 translated
#[test]
fn binary_deserialize_real() {
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(binary(&[
        0x72, 0x41, 0x2c, 0xec, 0xf6, 0x77, 0xce, 0xd9, 0x17,
    ]))
    .expect("OSDParser DeserializeLLSDBinary real");
    assert_osd(actual, &Expected::Real(947_835.234));
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeReal::test 94d74ae4767824e9702515204529543281b83521a085343c76204650ec96ed57 translated
#[test]
fn binary_serialize_real() {
    let fixture = binary(&[0x72, 0x41, 0x2c, 0xec, 0xf6, 0x77, 0xce, 0xd9, 0x17]);
    let actual = OSDParser::serialize_llsd_binary_with_osd(make(&Expected::Real(947_835.234)))
        .expect("OSDParser SerializeLLSDBinary real");
    assert_bytes_eq(&actual, &fixture);
    let actual = OSDParser::serialize_llsd_binary_with_osd(make(&Expected::Real(947_835.234)))
        .expect("OSDParser SerializeLLSDBinary real again");
    assert_bytes_eq(&actual, &fixture);
}

const UUID_TEXT: &str = "97f4aeca-88a1-42a1-b385-b97b18abb255";
const UUID_BYTES: &[u8] = &[
    0x75, 0x97, 0xf4, 0xae, 0xca, 0x88, 0xa1, 0x42, 0xa1, 0xb3, 0x85, 0xb9, 0x7b, 0x18, 0xab, 0xb2,
    0x55,
];

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeUUID::test c1a9206927342fecc0c9ff4ed4b80cc50f288b794996e1668ed4b6a6433ea977 translated
#[test]
fn binary_deserialize_uuid() {
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(binary(UUID_BYTES))
        .expect("OSDParser DeserializeLLSDBinary UUID");
    assert_osd(actual, &Expected::Uuid(UUID_TEXT));
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(binary(&[
        0x75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    ]))
    .expect("OSDParser DeserializeLLSDBinary zero UUID");
    assert_osd(
        actual,
        &Expected::Uuid("00000000-0000-0000-0000-000000000000"),
    );
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeUUID::test 5a236b468cedd7667d58641cb067ce30f6135aa95f2291538083e4254f52c2ad translated
#[test]
fn binary_serialize_uuid() {
    let fixture = binary(UUID_BYTES);
    let actual = OSDParser::serialize_llsd_binary_with_osd(make(&Expected::Uuid(UUID_TEXT)))
        .expect("OSDParser SerializeLLSDBinary UUID");
    assert_bytes_eq(&actual, &fixture);
    let actual = OSDParser::serialize_llsd_binary_with_osd(make(&Expected::Uuid(UUID_TEXT)))
        .expect("OSDParser SerializeLLSDBinary UUID again");
    assert_bytes_eq(&actual, &fixture);
    let zero = binary(&[0x75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
    let expected = Expected::Uuid("00000000-0000-0000-0000-000000000000");
    let actual = OSDParser::serialize_llsd_binary_with_osd(make(&expected))
        .expect("OSDParser SerializeLLSDBinary zero UUID");
    assert_bytes_eq(&actual, &zero);
    let actual = OSDParser::serialize_llsd_binary_with_osd(make(&expected))
        .expect("OSDParser SerializeLLSDBinary zero UUID again");
    assert_bytes_eq(&actual, &zero);
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeLLSDBinary::test b2cad2218f203d740c2863713248bc0f8083980f30c34cc244535eebc5f1aae1 translated
#[test]
fn binary_deserialize_llsd_binary() {
    let mut fixture = vec![0x62, 0, 0, 0, 0x34];
    fixture.extend_from_slice(BINARY_STRING_CONTENT);
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(binary(&fixture))
        .expect("OSDParser DeserializeLLSDBinary binary");
    assert_osd(actual, &Expected::Binary(BINARY_STRING_CONTENT));
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeLLSDBinary::test b715f3475dfe6e0876409a10c55548e345b7caf332939ff25489662500e05511 translated
#[test]
fn binary_serialize_llsd_binary() {
    let mut fixture = vec![0x62, 0, 0, 0, 0x34];
    fixture.extend_from_slice(BINARY_STRING_CONTENT);
    let actual =
        OSDParser::serialize_llsd_binary_with_osd(make(&Expected::Binary(BINARY_STRING_CONTENT)))
            .expect("OSDParser SerializeLLSDBinary binary");
    assert_bytes_eq(&actual, &binary(&fixture));
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeString::test d95f0156c50cd49eef0d8da231bf9128e95b274de92ac88409294ef9f925bada translated
#[test]
fn binary_deserialize_string() {
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(binary(&[0x73, 0, 0, 0, 0]))
        .expect("OSDParser DeserializeLLSDBinary empty string");
    assert_osd(actual, &Expected::String(""));
    let text = "abcdefghijklmnopqrstuvwxyz01234567890";
    let mut value = vec![0x73, 0, 0, 0, 0x25];
    value.extend_from_slice(text.as_bytes());
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(binary(&value))
        .expect("OSDParser DeserializeLLSDBinary string");
    assert_osd(actual, &Expected::String(text));
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeString::test 75b2c0e402cfdea326a1262287172353538d73ce343d7df99ec51f8531340cab translated
#[test]
fn binary_serialize_string() {
    let text = "abcdefghijklmnopqrstuvwxyz01234567890";
    let mut value = vec![0x73, 0, 0, 0, 0x25];
    value.extend_from_slice(text.as_bytes());
    let actual = OSDParser::serialize_llsd_binary_with_osd(make(&Expected::String(text)))
        .expect("OSDParser SerializeLLSDBinary string");
    assert_bytes_eq(&actual, &binary(&value));
    for text in ["ƖȔȠȨɆɒ", "𐄷"] {
        let encoded = OSDParser::serialize_llsd_binary_with_osd(make(&Expected::String(text)))
            .expect("OSDParser SerializeLLSDBinary Unicode string");
        let actual = OSDParser::deserialize_llsd_binary_with_bytes(encoded)
            .expect("OSDParser DeserializeLLSDBinary Unicode string");
        assert_osd(actual, &Expected::String(text));
    }
}

const URI_TEXT: &str = "http://www.testurl.test/";
const URI_VALUE: &[u8] = &[
    0x6c, 0, 0, 0, 0x18, b'h', b't', b't', b'p', b':', b'/', b'/', b'w', b'w', b'w', b'.', b't',
    b'e', b's', b't', b'u', b'r', b'l', b'.', b't', b'e', b's', b't', b'/',
];

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeURI::test 3ff6c2dce1e709e446259c9154dbe297ccb21b8bff87be8b53cbf43356f0ccf7 translated
#[test]
fn binary_deserialize_uri() {
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(binary(URI_VALUE))
        .expect("OSDParser DeserializeLLSDBinary URI");
    assert_osd(actual, &Expected::Uri(URI_TEXT));
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeURI::test 20914654e0b2b746d95ef1f7664e1bd732116326d45d1b823e484032edb1a7e8 translated
#[test]
fn binary_serialize_uri() {
    let actual = OSDParser::serialize_llsd_binary_with_osd(make(&Expected::Uri(URI_TEXT)))
        .expect("OSDParser SerializeLLSDBinary URI");
    assert_bytes_eq(&actual, &binary(URI_VALUE));
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeDateTime::test b417d525ccfeb449264e09dfe0589bd920429ade3014c8d24f8d7d913f1d6145 translated
#[test]
fn binary_deserialize_date_time() {
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(binary(&[
        100, 0, 0, 192, 141, 167, 222, 209, 65,
    ]))
    .expect("OSDParser DeserializeLLSDBinary date");
    assert_osd(actual, &Expected::Date(utc(1_199_218_231, 0)));
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeDateTime::test 5bb705bbd2f45058eb8fc498ca4f7a0318b448f2e175e21e760ff7156ecbce0f translated
#[test]
fn binary_serialize_date_time() {
    let expected = Expected::Date(utc(1_199_218_231, 0));
    let actual = OSDParser::serialize_llsd_binary_with_osd(make(&expected))
        .expect("OSDParser SerializeLLSDBinary date");
    assert_bytes_eq(&actual, &binary(&[100, 0, 0, 192, 141, 167, 222, 209, 65]));
    for expected in [
        Expected::Date(utc(1_262_161_510, 0)),
        Expected::Date(utc(1_289_470_100, 0)),
    ] {
        let encoded = OSDParser::serialize_llsd_binary_with_osd(make(&expected))
            .expect("OSDParser SerializeLLSDBinary date round trip");
        let actual = OSDParser::deserialize_llsd_binary_with_bytes(encoded)
            .expect("OSDParser DeserializeLLSDBinary date round trip");
        assert_osd(actual, &expected);
    }
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeArray::test 72b9700cfe07cb399985db485a75f34e483ddab520e26906995a601014451e53 translated
#[test]
fn binary_deserialize_array() {
    for (fixture, expected) in [
        (vec![0x5b, 0, 0, 0, 0, 0x5d], Expected::Array(vec![])),
        (
            vec![0x5b, 0, 0, 0, 1, 0x69, 0, 0, 0, 0, 0x5d],
            Expected::Array(vec![Expected::Integer(0)]),
        ),
        (
            vec![0x5b, 0, 0, 0, 2, 0x69, 0, 0, 0, 0, 0x69, 0, 0, 0, 0, 0x5d],
            Expected::Array(vec![Expected::Integer(0), Expected::Integer(0)]),
        ),
    ] {
        let actual = OSDParser::deserialize_llsd_binary_with_bytes(binary(&fixture))
            .expect("OSDParser DeserializeLLSDBinary array");
        assert_osd(actual, &expected);
    }
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeArray::test 2a0e692a44bae8b3d058524a765e57355fec7bda6ae9a063465332acce2eb9f8 translated
#[test]
fn binary_serialize_array() {
    for (expected, fixture) in [
        (Expected::Array(vec![]), vec![0x5b, 0, 0, 0, 0, 0x5d]),
        (
            Expected::Array(vec![Expected::Integer(0)]),
            vec![0x5b, 0, 0, 0, 1, 0x69, 0, 0, 0, 0, 0x5d],
        ),
        (
            Expected::Array(vec![Expected::Integer(0), Expected::Integer(0)]),
            vec![0x5b, 0, 0, 0, 2, 0x69, 0, 0, 0, 0, 0x69, 0, 0, 0, 0, 0x5d],
        ),
    ] {
        let actual = OSDParser::serialize_llsd_binary_with_osd(make(&expected))
            .expect("OSDParser SerializeLLSDBinary array");
        assert_bytes_eq(&actual, &binary(&fixture));
    }
    for (expected, fixture) in [
        (Expected::Array(vec![]), vec![0x5b, 0, 0, 0, 0, 0x5d]),
        (
            Expected::Array(vec![Expected::Integer(0)]),
            vec![0x5b, 0, 0, 0, 1, 0x69, 0, 0, 0, 0, 0x5d],
        ),
        (
            Expected::Array(vec![Expected::Integer(0), Expected::Integer(0)]),
            vec![0x5b, 0, 0, 0, 2, 0x69, 0, 0, 0, 0, 0x69, 0, 0, 0, 0, 0x5d],
        ),
    ] {
        let actual = OSDParser::serialize_llsd_binary_with_osd_boolean(make(&expected), false)
            .expect("OSDParser SerializeLLSDBinary array without header");
        assert_bytes_eq(&actual, &fixture);
    }
}

const SIMPLE_MAP_VALUE: &[u8] = &[
    0x7b, 0, 0, 0, 1, 0x6b, 0, 0, 0, 4, b't', b'e', b's', b't', 0x69, 0, 0, 0, 0, 0x7d,
];
const SIMPLE_MAP_TWO_VALUE: &[u8] = &[
    0x7b, 0, 0, 0, 3, 0x6b, 0, 0, 0, 4, b't', b'e', b's', b't', 0x21, 0x6b, 0, 0, 0, 4, b't', b'e',
    b's', b'1', 0x73, 0, 0, 0, 3, b'a', b'h', b'a', 0x6b, 0, 0, 0, 4, b't', b'0', b's', b't', 0x69,
    0, 0, 0, 0xf1, 0x7d,
];

fn simple_map_two() -> Expected {
    Expected::Map(vec![
        ("test", Expected::Undef),
        ("tes1", Expected::String("aha")),
        ("t0st", Expected::Integer(241)),
    ])
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeDictionary::test b2c5f1535e388417b7d4561b0e69de7e9f96468bd101864e3ba63deb95a872de translated
#[test]
fn binary_deserialize_dictionary() {
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(binary(&[0x7b, 0, 0, 0, 0, 0x7d]))
        .expect("OSDParser DeserializeLLSDBinary empty map");
    assert_osd(actual, &Expected::Map(vec![]));
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(binary(SIMPLE_MAP_VALUE))
        .expect("OSDParser DeserializeLLSDBinary map");
    assert_osd(actual, &Expected::Map(vec![("test", Expected::Integer(0))]));
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(binary(SIMPLE_MAP_TWO_VALUE))
        .expect("OSDParser DeserializeLLSDBinary composite map");
    assert_osd(actual, &simple_map_two());
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeDictionary::test 01b7a8fc0c0f7cc588ed23d15f01e30d8a5d9cd07954e84046945b95cd031373 translated
#[test]
fn binary_serialize_dictionary() {
    let expected = Expected::Map(vec![]);
    let actual = OSDParser::serialize_llsd_binary_with_osd(make(&expected))
        .expect("OSDParser SerializeLLSDBinary empty map");
    assert_bytes_eq(&actual, &binary(&[0x7b, 0, 0, 0, 0, 0x7d]));
    let expected = Expected::Map(vec![("test", Expected::Integer(0))]);
    let actual = OSDParser::serialize_llsd_binary_with_osd(make(&expected))
        .expect("OSDParser SerializeLLSDBinary map");
    assert_bytes_eq(&actual, &binary(SIMPLE_MAP_VALUE));
    for expected in [
        simple_map_two(),
        Expected::Map(vec![("𐄷", Expected::String("𐄷"))]),
    ] {
        let encoded = OSDParser::serialize_llsd_binary_with_osd(make(&expected))
            .expect("OSDParser SerializeLLSDBinary map round trip");
        let actual = OSDParser::deserialize_llsd_binary_with_bytes(encoded)
            .expect("OSDParser DeserializeLLSDBinary map round trip");
        assert_osd(actual, &expected);
    }
}

fn nested_value() -> Expected {
    Expected::Array(vec![
        Expected::Map(vec![
            ("test", Expected::String("what")),
            (
                "t0st",
                Expected::Array(vec![Expected::Integer(1), Expected::Integer(2)]),
            ),
        ]),
        Expected::Integer(124),
        Expected::Integer(987),
    ])
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.DeserializeNestedComposite::test 60f8cf739fecf42c98ae4e0878d06234278b9d8370afc38f0d501d62f8ff9cdf translated
#[test]
fn binary_deserialize_nested_composite() {
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(binary(BINARY_NESTED_VALUE))
        .expect("OSDParser DeserializeLLSDBinary nested composite");
    assert_osd(actual, &nested_value());
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeNestedComposite::test 092b52da3f0cf720595fdb84c929c8ad033c60ff978429cb1d27f9e215936b10 translated
#[test]
fn binary_serialize_nested_composite() {
    let expected = nested_value();
    let encoded = OSDParser::serialize_llsd_binary_with_osd(make(&expected))
        .expect("OSDParser SerializeLLSDBinary nested composite");
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(encoded)
        .expect("OSDParser DeserializeLLSDBinary nested composite");
    assert_osd(actual, &expected);
}

// parity-case: LibreMetaverse.Tests/BinaryLLSDTests.cs::BinarySDTests.SerializeLongMessage::test b49afb91578e6c19193cd48acf161a9f8c57bbd20245783054709a509f63780e translated
#[test]
fn binary_serialize_long_message() {
    let one = "asdklfjasadlfkjaerotiudfgjkhsdklgjhsdklfghasdfklhjasdfkjhasdfkljahsdfjklaasdfkj8";
    let two = "asdfkjlaaweoiugsdfjkhsdfg,.mnasdgfkljhrtuiohfgl�kajsdfoiwghjkdlaaaaseldkfjgheus9";
    let expected = Expected::Map(vec![
        ("testOne", Expected::String(one)),
        ("testTwo", Expected::String(two)),
        ("testThree", Expected::String(one)),
        ("testFour", Expected::String(two)),
        ("testFive", Expected::String(one)),
        ("testSix", Expected::String(two)),
        ("testSeven", Expected::String(one)),
        ("testEight", Expected::String(two)),
        ("testNine", Expected::String(one)),
        ("testTen", Expected::String(two)),
    ]);
    let encoded = OSDParser::serialize_llsd_binary_with_osd(make(&expected))
        .expect("OSDParser SerializeLLSDBinary long message");
    let actual = OSDParser::deserialize_llsd_binary_with_bytes(encoded)
        .expect("OSDParser DeserializeLLSDBinary long message");
    assert_osd(actual, &expected);
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.HelperFunctions::test a521ca5407ed3afd1d59f5b65a283bcebe9d34b4c384d68c5fc674b3a1eeb9df translated
#[test]
fn notation_helper_functions() {
    for (remaining, characters, offset, expected) in [
        ("test1tast2test3", "test", 0, 4),
        ("1tast2test3", "1te", 0, 2),
        ("ast2test3", "ast2tes", 1, 1),
        ("ast2test3", "ast2tes", 0, 7),
        ("t3", "t3aa", 0, 2),
    ] {
        let characters = characters
            .encode_utf16()
            .map(Utf16CodeUnit)
            .collect::<Vec<_>>();
        assert_eq!(
            OSDParser::buffer_characters_equal(StringReader(remaining.into()), characters, offset,)
                .expect("BufferCharactersEqual"),
            expected
        );
    }
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeUndef::test 8c802fb14244cb423223c7c25702e4120da261f5dd1b378d2eca597277371406 translated
#[test]
fn notation_deserialize_undef() {
    let actual = OSDParser::deserialize_llsd_notation_with_string("!".into())
        .expect("OSDParser DeserializeLLSDNotation");
    assert_osd(actual, &Expected::Undef);
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeUndef::test 2ceee97b1826a3ba88a50798dba184b48998196192e31527171a9980f06c3281 translated
#[test]
fn notation_serialize_undef() {
    let encoded = OSDParser::serialize_llsd_notation(make(&Expected::Undef))
        .expect("OSDParser SerializeLLSDNotation");
    let actual = OSDParser::deserialize_llsd_notation_with_string(encoded)
        .expect("OSDParser DeserializeLLSDNotation");
    assert_osd(actual, &Expected::Undef);
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeBoolean::test 9279106aebdcab8c8b179963bd3e9beb3d6fec89e53c376e56eed7b7c17213a2 translated
#[test]
fn notation_deserialize_boolean() {
    for input in ["true", "t", "TRUE", "T", "1"] {
        let actual = OSDParser::deserialize_llsd_notation_with_string(input.into())
            .expect("OSDParser DeserializeLLSDNotation true");
        assert_osd(actual, &Expected::Bool(true));
    }
    for input in ["false", "f", "FALSE", "F", "0"] {
        let actual = OSDParser::deserialize_llsd_notation_with_string(input.into())
            .expect("OSDParser DeserializeLLSDNotation false");
        assert_osd(actual, &Expected::Bool(false));
    }
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeBoolean::test 101bb91e58a4fe924f6137b948c4e5d3efa46875a8a118031fc657b59f6f4bdf translated
#[test]
fn notation_serialize_boolean() {
    for expected in [Expected::Bool(true), Expected::Bool(false)] {
        let encoded = OSDParser::serialize_llsd_notation(make(&expected))
            .expect("OSDParser SerializeLLSDNotation boolean");
        let actual = OSDParser::deserialize_llsd_notation_with_string(encoded)
            .expect("OSDParser DeserializeLLSDNotation boolean");
        assert_osd(actual, &expected);
    }
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeInteger::test 5a8e2d8eeab4fbdc46b0487fb65cf35905c3e640e1a06e227443e5aae990a265 translated
#[test]
fn notation_deserialize_integer() {
    let actual = OSDParser::deserialize_llsd_notation_with_string("i12319423".into())
        .expect("OSDParser DeserializeLLSDNotation positive integer");
    assert_osd(actual, &Expected::Integer(12_319_423));
    let actual = OSDParser::deserialize_llsd_notation_with_string("i-489234".into())
        .expect("OSDParser DeserializeLLSDNotation negative integer");
    assert_osd(actual, &Expected::Integer(-489_234));
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeInteger::test 8bb1b1752c8bc23499b6f77167fc307e22a6572719c45a36280bee36ff645d93 translated
#[test]
fn notation_serialize_integer() {
    let original = make(&Expected::Integer(12_319_423));
    let encoded = OSDParser::serialize_llsd_notation(original)
        .expect("OSDParser SerializeLLSDNotation integer");
    let deserialized = OSDParser::deserialize_llsd_notation_with_string(encoded)
        .expect("OSDParser DeserializeLLSDNotation integer");
    assert_eq!(deserialized.type_(), OSDType::Integer);
    // The upstream assertion intentionally reads the original value here.
    assert_eq!(
        make(&Expected::Integer(12_319_423))
            .as_integer()
            .expect("OSD AsInteger"),
        12_319_423
    );
    let expected = Expected::Integer(-71_892_034);
    let encoded = OSDParser::serialize_llsd_notation(make(&expected))
        .expect("OSDParser SerializeLLSDNotation negative integer");
    let actual = OSDParser::deserialize_llsd_notation_with_string(encoded)
        .expect("OSDParser DeserializeLLSDNotation negative integer");
    assert_osd(actual, &expected);
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeReal::test ffe387948b423b9fe47e4b3df9ae7c21306200f3afba8cd4944933c274691d79 translated
#[test]
fn notation_deserialize_real() {
    for (input, expected) in [
        ("r1123412345.465711", 1_123_412_345.465_711),
        ("r-11234684.923411", -11_234_684.923_411),
        ("r1", 1.0),
        ("r2.0193899999999998204e-06", 2.019_389_999_999_999_8e-6),
        ("r0", 0.0),
    ] {
        let actual = OSDParser::deserialize_llsd_notation_with_string(input.into())
            .expect("OSDParser DeserializeLLSDNotation real");
        assert_osd(actual, &Expected::Real(expected));
    }
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeReal::test c40b06b0496191186c6cdc5cc9e03952cb3a31fc8fdc98ecd671c446cbd0c0be translated
#[test]
fn notation_serialize_real() {
    for value in [
        12_987_234.723_847,
        -32_347_892.234_234,
        f64::MAX,
        f64::MIN,
        -1.112_312_3e50,
        2.019_389_999_999_999_8e-6,
    ] {
        let expected = Expected::Real(value);
        let encoded = OSDParser::serialize_llsd_notation(make(&expected))
            .expect("OSDParser SerializeLLSDNotation real");
        let actual = OSDParser::deserialize_llsd_notation_with_string(encoded)
            .expect("OSDParser DeserializeLLSDNotation real");
        assert_osd(actual, &expected);
    }
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeUUID::test 1ab05a03d422d0450dba3571f009ee9af6ee151d8a1ee1c248cc48f93196d242 translated
#[test]
fn notation_deserialize_uuid() {
    let actual = OSDParser::deserialize_llsd_notation_with_string(
        "u97f4aeca-88a1-42a1-b385-b97b18abb255".into(),
    )
    .expect("OSDParser DeserializeLLSDNotation UUID");
    assert_osd(actual, &Expected::Uuid(UUID_TEXT));
    let actual = OSDParser::deserialize_llsd_notation_with_string(
        "u00000000-0000-0000-0000-000000000000".into(),
    )
    .expect("OSDParser DeserializeLLSDNotation zero UUID");
    assert_osd(
        actual,
        &Expected::Uuid("00000000-0000-0000-0000-000000000000"),
    );
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeUUID::test 122f917c29076476e11dc9d36f943e4910168a516be234189047e8b51b09e539 translated
#[test]
fn notation_serialize_uuid() {
    for expected in [
        Expected::Uuid(UUID_TEXT),
        Expected::Uuid("00000000-0000-0000-0000-000000000000"),
    ] {
        let encoded = OSDParser::serialize_llsd_notation(make(&expected))
            .expect("OSDParser SerializeLLSDNotation UUID");
        let actual = OSDParser::deserialize_llsd_notation_with_string(encoded)
            .expect("OSDParser DeserializeLLSDNotation UUID");
        assert_osd(actual, &expected);
    }
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeString::test a29dc440ccde574c1302c57d3ef4c5404aa4fd419a5f160ba4920ab5a3349cc7 translated
#[test]
fn notation_deserialize_string() {
    for (input, expected) in [
        ("''", ""),
        (r#"'test\'\"test'"#, "test'\"test"),
        ("'test \\\\lest'", "test \\\\lest"),
        ("'aa\t la'", "aa\t la"),
        ("'\\\\'", "\\"),
        (r#"s(10)"1234567890""#, "1234567890"),
        (r#"s(5)"\\\""#, "\\\\\\\\\\"),
        (
            r#""aouAOUhsdjklfghskldjfghqeiurtzwieortzaslxfjkgh""#,
            "aouAOUhsdjklfghskldjfghqeiurtzwieortzaslxfjkgh",
        ),
    ] {
        let actual = OSDParser::deserialize_llsd_notation_with_string(input.into())
            .expect("OSDParser DeserializeLLSDNotation string");
        assert_osd(actual, &Expected::String(expected));
    }
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeString::test 1cca05a4cf0fbbd516f1fe1c43b9fc617840a6374680c9085087adc1d9ae41cd translated
#[test]
fn notation_serialize_string() {
    for value in [
        "",
        "\\",
        "\"\"",
        "������-these-should-be-some-german-umlauts",
        "\t\n\r",
        concat!(
            "asdkjfhaksldjfhalskdjfhaklsjdfhaklsjdhjgzqeuiowrtzserghsldfg",
            "asdlkfhqeiortzsdkfjghslkdrjtzsoidklghuisoehiguhsierughaishdl",
            "asdfkjhueiorthsgsdkfughaslkdfjshldkfjghsldkjghsldkfghsdklghs",
            "wopeighisdjfghklasdfjghsdklfgjhsdklfgjshdlfkgjshdlfkgjshdlfk",
        ),
        "all is N\"\\'othing and n'oting is all",
        "very\"british is this.",
        "𐄷",
    ] {
        let expected = Expected::String(value);
        let encoded = OSDParser::serialize_llsd_notation(make(&expected))
            .expect("OSDParser SerializeLLSDNotation string");
        let actual = OSDParser::deserialize_llsd_notation_with_string(encoded)
            .expect("OSDParser DeserializeLLSDNotation string");
        assert_osd(actual, &expected);
    }
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeURI::test 4ed3cbdce17f8e7e2b3294a8a85db9775458fcc0fecd9052bfef4110280ef55d translated
#[test]
fn notation_deserialize_uri() {
    let actual = OSDParser::deserialize_llsd_notation_with_string(
        r#"l"http://test.com/test test>\"/&yes""#.into(),
    )
    .expect("OSDParser DeserializeLLSDNotation absolute URI");
    assert_osd(
        actual,
        &Expected::UriString("http://test.com/test%20test%3E%22/&yes"),
    );
    let actual = OSDParser::deserialize_llsd_notation_with_string(
        r#"l"test/test/test?test=1&toast=2""#.into(),
    )
    .expect("OSDParser DeserializeLLSDNotation relative URI");
    assert_osd(
        actual,
        &Expected::UriString("test/test/test?test=1&toast=2"),
    );
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeURI::test ed474ac9185db97d779cb9c598d6908c2d5e7c23cc09871f75ba04161cb843f1 translated
#[test]
fn notation_serialize_uri() {
    for expected in [
        Expected::Uri("http://test.org/test test>\\\"/&yes\""),
        Expected::Uri("test/test/near/the/end?test=1"),
    ] {
        let encoded = OSDParser::serialize_llsd_notation(make(&expected))
            .expect("OSDParser SerializeLLSDNotation URI");
        let actual = OSDParser::deserialize_llsd_notation_with_string(encoded)
            .expect("OSDParser DeserializeLLSDNotation URI");
        assert_osd(actual, &expected);
    }
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeDate::test bd7b2ae076622734844b844c374223e174706f48f37bf18d875ecf3b14c81e4c translated
#[test]
fn notation_deserialize_date() {
    let actual =
        OSDParser::deserialize_llsd_notation_with_string(r#"d"2007-12-31T20:49:10Z""#.into())
            .expect("OSDParser DeserializeLLSDNotation date");
    assert_osd(actual, &Expected::Date(utc(1_199_134_150, 0)));
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeDate::test 987524a4caf7bdfaf3db138493cdc1a7a585b7730a11d8feea92e32860453997 translated
#[test]
fn notation_serialize_date() {
    for expected in [
        Expected::Date(utc(1_123_672_984, 0)),
        Expected::Date(utc(1_286_838_010, 100)),
        Expected::Date(utc(1_262_161_510, 0)),
    ] {
        let encoded = OSDParser::serialize_llsd_notation(make(&expected))
            .expect("OSDParser SerializeLLSDNotation date");
        let actual = OSDParser::deserialize_llsd_notation_with_string(encoded)
            .expect("OSDParser DeserializeLLSDNotation date");
        assert_osd(actual, &expected);
    }
}

const NOTATION_BINARY: &[u8] = &[
    0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0x0b, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
];

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeBinary::test 07f940143dd6212080fee783bf3c493157a5099fbd0646bf91a5024d12e55d6b translated
#[test]
fn notation_serialize_binary() {
    let expected = Expected::Binary(NOTATION_BINARY);
    let encoded = OSDParser::serialize_llsd_notation(make(&expected))
        .expect("OSDParser SerializeLLSDNotation binary");
    let actual = OSDParser::deserialize_llsd_notation_with_string(encoded)
        .expect("OSDParser DeserializeLLSDNotation binary");
    assert_osd(actual, &expected);
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeArray::test b1313ef5f375a1511fffe4c593dedc046e4ebfcca2a41cac6fafa65b99abc38e translated
#[test]
fn notation_deserialize_array() {
    for (input, expected) in [
        ("[]", Expected::Array(vec![])),
        ("[ i0 ]", Expected::Array(vec![Expected::Integer(0)])),
        (
            "[ i0, i1 ]",
            Expected::Array(vec![Expected::Integer(0), Expected::Integer(1)]),
        ),
        (
            " [ \"testtest\", \"aha\",t,f,i1, r1.2, [ i1] ] ",
            Expected::Array(vec![
                Expected::String("testtest"),
                Expected::String("aha"),
                Expected::Bool(true),
                Expected::Bool(false),
                Expected::Integer(1),
                Expected::Real(1.2),
                Expected::Array(vec![Expected::Integer(1)]),
            ]),
        ),
    ] {
        let actual = OSDParser::deserialize_llsd_notation_with_string(input.into())
            .expect("OSDParser DeserializeLLSDNotation array");
        assert_osd(actual, &expected);
    }
}

fn notation_composite_array() -> Expected {
    Expected::Array(vec![
        Expected::Integer(123_234),
        Expected::String("asedkfjhaqweiurohzasdf"),
        Expected::Array(vec![
            Expected::Integer(123_234),
            Expected::String("asedkfjhaqweiurohzasdf"),
        ]),
    ])
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeArray::test 2c0a7af66c707280621a03423a6b56b24acdcc26b5f34d6bc5427ba98a111c50 translated
#[test]
fn notation_serialize_array() {
    for expected in [Expected::Array(vec![]), notation_composite_array()] {
        let encoded = OSDParser::serialize_llsd_notation(make(&expected))
            .expect("OSDParser SerializeLLSDNotation array");
        let actual = OSDParser::deserialize_llsd_notation_with_string(encoded)
            .expect("OSDParser DeserializeLLSDNotation array");
        assert_osd(actual, &expected);
    }
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeMap::test 75348b6dde6ff642f3f19e48009565fb82410ed522583d20c3833bdd4121b258 translated
#[test]
fn notation_deserialize_map() {
    let actual = OSDParser::deserialize_llsd_notation_with_string(" { } ".into())
        .expect("OSDParser DeserializeLLSDNotation empty map");
    assert_osd(actual, &Expected::Map(vec![]));

    let actual = OSDParser::deserialize_llsd_notation_with_string(" { \"test\":i2 } ".into())
        .expect("OSDParser DeserializeLLSDNotation one-entry map");
    assert_osd(actual, &Expected::Map(vec![("test", Expected::Integer(2))]));

    let actual = OSDParser::deserialize_llsd_notation_with_string(
        r#" { 'test':"testtesttest", 'aha':"muahahaha" , "anywhere":! } "#.into(),
    )
    .expect("OSDParser DeserializeLLSDNotation string map");
    let OSD::Map(mut actual) = actual else {
        panic!("expected OSD map");
    };
    assert_eq!(actual.len(), 3);
    assert_osd(
        actual.remove("test").expect("test"),
        &Expected::String("testtesttest"),
    );
    assert_osd(
        actual.remove("aha").expect("aha"),
        &Expected::String("muahahaha"),
    );
    assert_eq!(
        actual.get("self").unwrap_or(&OSD::Undefined).type_(),
        OSDType::Unknown
    );

    let actual = OSDParser::deserialize_llsd_notation_with_string(
        r#" { 'test' : { 'test' : i1, 't0st' : r2.5 }, 'tist' : "hello world!", 'tast' : "last" } "#.into(),
    )
    .expect("OSDParser DeserializeLLSDNotation nested map");
    assert_osd(
        actual,
        &Expected::Map(vec![
            (
                "test",
                Expected::Map(vec![
                    ("test", Expected::Integer(1)),
                    ("t0st", Expected::Real(2.5)),
                ]),
            ),
            ("tist", Expected::String("hello world!")),
            ("tast", Expected::String("last")),
        ]),
    );
}

fn notation_composite_map() -> Expected {
    Expected::Map(vec![
        ("test0", Expected::Integer(123_234)),
        ("test1", Expected::String("asedkfjhaqweiurohzasdf")),
        (
            "test2",
            Expected::Map(vec![
                ("test0", Expected::Integer(123_234)),
                ("test1", Expected::String("asedkfjhaqweiurohzasdf")),
            ]),
        ),
    ])
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeMap::test 71bf4cf86acc617623d904f5d1a1f892e45e5f6298e057ab7670281da1d6b541 translated
#[test]
fn notation_serialize_map() {
    for expected in [
        Expected::Map(vec![]),
        notation_composite_map(),
        Expected::Map(vec![("𐄷", Expected::String("𐄷"))]),
    ] {
        let encoded = OSDParser::serialize_llsd_notation(make(&expected))
            .expect("OSDParser SerializeLLSDNotation map");
        let actual = OSDParser::deserialize_llsd_notation_with_string(encoded)
            .expect("OSDParser DeserializeLLSDNotation map");
        assert_osd(actual, &expected);
    }
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.DeserializeRealWorldExamples::test 684c4f3ad342010bc466699fc921375f3df16b63c600ac85f970d63b57d62ae2 translated
#[test]
fn notation_deserialize_real_world_examples() {
    let input = r#"
[
  {'destination':'http://secondlife.com'},
  {'version':i1},
  {
    'agent_id':u3c115e51-04f4-523c-9fa6-98aff1034730,
    'session_id':u2c585cec-038c-40b0-b42e-a25ebab4d132,
    'circuit_code':i1075,
    'first_name':'Phoenix',
    'last_name':'Linden',
    'position':[r70.9247,r254.378,r38.7304],
    'look_at':[r-0.043753,r-0.999042,r0],
    'granters':[ua2e76fcd-9360-4f6d-a924-000000000003],
    'attachment_data':
    [
      {
        'attachment_point':i2,
        'item_id':ud6852c11-a74e-309a-0462-50533f1ef9b3,
        'asset_id':uc69b29b1-8944-58ae-a7c5-2ca7b23e22fb
      },
      {
        'attachment_point':i10,
        'item_id':uff852c22-a74e-309a-0462-50533f1ef900,
        'asset_id':u5868dd20-c25a-47bd-8b4c-dedc99ef9479
      }
    ]
  }
]"#;
    let actual = OSDParser::deserialize_llsd_notation_with_string(input.into())
        .expect("OSDParser DeserializeLLSDNotation real-world example");
    assert_eq!(actual.type_(), OSDType::Array);
    let OSD::Array(mut array) = actual else {
        panic!("expected top-level OSD array");
    };
    assert_eq!(array.len(), 3);
    let OSD::Map(first) = array.remove(0) else {
        panic!("expected first OSD map");
    };
    assert_eq!(
        first
            .get("destination")
            .expect("destination")
            .as_string()
            .expect("destination string"),
        "http://secondlife.com"
    );
    let OSD::Map(second) = array.remove(0) else {
        panic!("expected second OSD map");
    };
    assert_osd(
        second
            .into_iter()
            .find(|(key, _)| key == "version")
            .expect("version")
            .1,
        &Expected::Integer(1),
    );
    let OSD::Map(mut third) = array.remove(0) else {
        panic!("expected third OSD map");
    };
    assert_osd(
        third.remove("session_id").expect("session_id"),
        &Expected::Uuid("2c585cec-038c-40b0-b42e-a25ebab4d132"),
    );
    assert_osd(
        third.remove("agent_id").expect("agent_id"),
        &Expected::Uuid("3c115e51-04f4-523c-9fa6-98aff1034730"),
    );
}

// parity-case: LibreMetaverse.Tests/NotationLLSDTests.cs::NotationSDTests.SerializeFormattedTest::test de64ee1e02e47116c580a7340e0ce8a908787eff63d46a56ee04379330932ee5 translated
#[test]
fn notation_serialize_formatted_test() {
    let input = Expected::Array(vec![
        Expected::Integer(1),
        Expected::Integer(1),
        Expected::Map(vec![
            ("test1", Expected::Integer(2)),
            ("test2", Expected::Integer(2)),
            (
                "test3",
                Expected::Array(vec![
                    Expected::String("asdflkhjasdhj"),
                    Expected::String("asdkfhasjkldfghsd"),
                ]),
            ),
        ]),
    ]);
    let formatted = OSDParser::serialize_llsd_notation_formatted(make(&input))
        .expect("OSDParser SerializeLLSDNotationFormatted");
    let actual = OSDParser::deserialize_llsd_notation_with_string(formatted)
        .expect("OSDParser DeserializeLLSDNotation");
    let OSD::Array(actual) = actual else {
        panic!("expected formatted top-level OSD array");
    };
    assert_eq!(actual.len(), 3);
    let mut actual = actual.into_iter();
    assert_osd(actual.next().expect("first item"), &Expected::Integer(1));
    assert_osd(actual.next().expect("second item"), &Expected::Integer(1));
    assert_eq!(actual.next().expect("third item").type_(), OSDType::Map);
}

// parity-case: LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeBoolean::test 06d71d5ad54dab8236458e6cf3c9893728d4a13c348441822f674164a285150b translated
#[test]
fn protobuf_serialize_boolean() {
    for expected in [Expected::Bool(true), Expected::Bool(false)] {
        let encoded = OSDParser::serialize_llsd_protobuf(make(&expected), None)
            .expect("OSDParser SerializeLLSDProtobuf boolean");
        let actual = OSDParser::deserialize_llsd_protobuf_with_bytes(encoded)
            .expect("OSDParser DeserializeLLSDProtobuf boolean");
        assert_osd(actual, &expected);
    }
}

// parity-case: LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeInteger::test 8a20e00e06a1a01a39c6cc3f1de100015abb0446ee07e42fbbfc89d4351d9f5b translated
#[test]
fn protobuf_serialize_integer() {
    for value in [0, 1_234_843, -54_321] {
        let expected = Expected::Integer(value);
        let encoded = OSDParser::serialize_llsd_protobuf(make(&expected), None)
            .expect("OSDParser SerializeLLSDProtobuf integer");
        let actual = OSDParser::deserialize_llsd_protobuf_with_bytes(encoded)
            .expect("OSDParser DeserializeLLSDProtobuf integer");
        assert_osd(actual, &expected);
    }
}

// parity-case: LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeReal::test 4aae9af41d534a2c4755f40f9da4d7b780a4552b52c7816d0aa70f640d64cfd3 translated
#[test]
fn protobuf_serialize_real() {
    let expected = Expected::Real(947_835.234);
    let encoded = OSDParser::serialize_llsd_protobuf(make(&expected), None)
        .expect("OSDParser SerializeLLSDProtobuf real");
    let actual = OSDParser::deserialize_llsd_protobuf_with_bytes(encoded)
        .expect("OSDParser DeserializeLLSDProtobuf real");
    assert_osd(actual, &expected);
}

// parity-case: LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeUUID::test 7fa09c08d627d04b66651d0f50cbf6a4373536315c121bab59f43b57c0cbf064 translated
#[test]
fn protobuf_serialize_uuid() {
    let expected = Expected::Uuid(UUID_TEXT);
    let encoded = OSDParser::serialize_llsd_protobuf(make(&expected), None)
        .expect("OSDParser SerializeLLSDProtobuf UUID");
    let actual = OSDParser::deserialize_llsd_protobuf_with_bytes(encoded)
        .expect("OSDParser DeserializeLLSDProtobuf UUID");
    assert_osd(actual, &expected);

    let zero = UUID::zero();
    let osd = OSD::from_uuid(zero).expect("OSD FromUUID zero");
    let encoded = OSDParser::serialize_llsd_protobuf(osd, None)
        .expect("OSDParser SerializeLLSDProtobuf zero UUID");
    let actual = OSDParser::deserialize_llsd_protobuf_with_bytes(encoded)
        .expect("OSDParser DeserializeLLSDProtobuf zero UUID");
    assert_eq!(actual.type_(), OSDType::UUID);
    assert!(
        actual
            .as_uuid()
            .expect("OSD AsUUID")
            .equals_with_uuid(UUID::zero())
    );
}

// parity-case: LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeString::test 880195caac721a93349f902efb2615342d84eca86a64c8340dd314044d8a3ade translated
#[test]
fn protobuf_serialize_string() {
    for expected in [
        Expected::String("abcdefghijklmnopqrstuvwxyz01234567890"),
        Expected::String(""),
    ] {
        let encoded = OSDParser::serialize_llsd_protobuf(make(&expected), None)
            .expect("OSDParser SerializeLLSDProtobuf string");
        let actual = OSDParser::deserialize_llsd_protobuf_with_bytes(encoded)
            .expect("OSDParser DeserializeLLSDProtobuf string");
        assert_osd(actual, &expected);
    }
}

// parity-case: LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeArray::test 2bdfc891534aeafa4a0729f4f3ba34d9fb4cc0ea4e88c6ac1aab63224b95f230 translated
#[test]
fn protobuf_serialize_array() {
    let expected = Expected::Array(vec![
        Expected::Integer(1),
        Expected::Integer(2),
        Expected::String("three"),
    ]);
    let encoded = OSDParser::serialize_llsd_protobuf(make(&expected), None)
        .expect("OSDParser SerializeLLSDProtobuf array");
    let actual = OSDParser::deserialize_llsd_protobuf_with_bytes(encoded)
        .expect("OSDParser DeserializeLLSDProtobuf array");
    assert_osd(actual, &expected);
}

// parity-case: LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeMap::test d2a14b977d843249e2569a2287981ee9fc903c07cf19b5e3cd613c340725de51 translated
#[test]
fn protobuf_serialize_map() {
    let expected = Expected::Map(vec![
        ("name", Expected::String("Test")),
        ("value", Expected::Integer(42)),
        ("enabled", Expected::Bool(true)),
    ]);
    let encoded = OSDParser::serialize_llsd_protobuf(make(&expected), None)
        .expect("OSDParser SerializeLLSDProtobuf map");
    let actual = OSDParser::deserialize_llsd_protobuf_with_bytes(encoded)
        .expect("OSDParser DeserializeLLSDProtobuf map");
    assert_osd(actual, &expected);
}

// parity-case: LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeNestedComposite::test bae0fbd2740466f84376f8f98ec4bf93143ce9cc7ad60cdd15907411280ff0a6 translated
#[test]
fn protobuf_serialize_nested_composite() {
    let expected = Expected::Array(vec![
        Expected::Map(vec![
            (
                "items",
                Expected::Array(vec![Expected::Integer(1), Expected::Integer(2)]),
            ),
            ("name", Expected::String("nested")),
        ]),
        Expected::Integer(124),
    ]);
    let encoded = OSDParser::serialize_llsd_protobuf(make(&expected), None)
        .expect("OSDParser SerializeLLSDProtobuf nested composite");
    let actual = OSDParser::deserialize_llsd_protobuf_with_bytes(encoded)
        .expect("OSDParser DeserializeLLSDProtobuf nested composite");
    assert_osd(actual, &expected);
}

// parity-case: LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.AutoDetectProtobuf::test 2c319b85ae1615fcb9c5804ac01bcb108c6ab235d51b971447fd2576054d8191 translated
#[test]
fn protobuf_auto_detect() {
    let encoded = OSDParser::serialize_llsd_protobuf(
        make(&Expected::String("test protobuf detection")),
        Some(true),
    )
    .expect("OSDParser SerializeLLSDProtobuf with header");
    let actual = OSDParser::deserialize_with_bytes(encoded).expect("OSDParser Deserialize bytes");
    assert_osd(actual, &Expected::String("test protobuf detection"));
}

const PROTOBUF_BINARY: &[u8] = &[1, 2, 3, 4, 0xff];

// parity-case: LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeBinary::test f5b3aa5e551371f05d90f20f5552844c71e9abb337d33ed178e72297e5d7435d translated
#[test]
fn protobuf_serialize_binary() {
    let expected = Expected::Binary(PROTOBUF_BINARY);
    let encoded = OSDParser::serialize_llsd_protobuf(make(&expected), None)
        .expect("OSDParser SerializeLLSDProtobuf binary");
    let actual = OSDParser::deserialize_llsd_protobuf_with_bytes(encoded)
        .expect("OSDParser DeserializeLLSDProtobuf binary");
    assert_osd(actual, &expected);
}

// parity-case: LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeDate::test 2a972308d04e49c41fabe1d240cd8d4398a53fa7264ffd588cedde7e0c76c9b9 translated
#[test]
fn protobuf_serialize_date() {
    let expected = utc(1_705_314_645, 0);
    let encoded = OSDParser::serialize_llsd_protobuf(make(&Expected::Date(expected)), None)
        .expect("OSDParser SerializeLLSDProtobuf date");
    let actual = OSDParser::deserialize_llsd_protobuf_with_bytes(encoded)
        .expect("OSDParser DeserializeLLSDProtobuf date");
    assert_eq!(actual.type_(), OSDType::Date);
    let actual = actual.as_date().expect("OSD AsDate");
    let difference = actual
        .duration_since(expected)
        .unwrap_or_else(|error| error.duration());
    assert!(difference.as_secs_f64() < 1.0);
}

// parity-case: LibreMetaverse.Tests/ProtobufTests.cs::ProtobufTests.SerializeUri::test 1561f2747cba4be4f9ab5af31d08f2a24e199e2193b3fcabb7925d79f4d70a5e translated
#[test]
fn protobuf_serialize_uri() {
    let expected = Expected::Uri("http://www.example.com/test");
    let encoded = OSDParser::serialize_llsd_protobuf(make(&expected), None)
        .expect("OSDParser SerializeLLSDProtobuf URI");
    let actual = OSDParser::deserialize_llsd_protobuf_with_bytes(encoded)
        .expect("OSDParser DeserializeLLSDProtobuf URI");
    assert_osd(actual, &expected);
}

// parity-case: LibreMetaverse.Tests/TypeTests.cs::TypeTests.LLSDTerseParsing::test c5fcc05c15fa60c43cd40f5fc2b1349d9fbd1f5bb3537d8b04e91f37302e77f1 translated
#[test]
fn llsd_terse_parsing() {
    let actual = OSDParser::deserialize_llsd_notation_with_string(
        "[r0.99967899999999998428,r-0.025334599999999998787,r0]".into(),
    )
    .expect("OSDParser DeserializeLLSDNotation first terse array");
    let OSD::Array(array) = actual else {
        panic!("expected OSD array");
    };
    assert_eq!(array.len(), 3);
    assert_close(array[0].as_real().expect("first real"), 0.999, 0.1);
    assert_close(array[1].as_real().expect("second real"), -0.02, 0.1);
    assert_eq!(array[2].as_real().expect("third real"), 0.0);

    let actual = OSDParser::deserialize_llsd_notation_with_string("[[r1,r1,r1],r0]".into())
        .expect("OSDParser DeserializeLLSDNotation nested terse array");
    let OSD::Array(mut array) = actual else {
        panic!("expected OSD array");
    };
    assert_eq!(array.len(), 2);
    assert_eq!(array[1].as_real().expect("outer real"), 0.0);
    let OSD::Array(inner) = array.remove(0) else {
        panic!("expected nested OSD array");
    };
    for item in inner {
        assert_eq!(item.as_real().expect("nested real"), 1.0);
    }

    let actual = OSDParser::deserialize_llsd_notation_with_string(
        "{'region_handle':[r255232, r256512], 'position':[r33.6, r33.71, r43.13], 'look_at':[r34.6, r33.71, r43.13]}".into(),
    )
    .expect("OSDParser DeserializeLLSDNotation terse map");
    let OSD::Map(map) = actual else {
        panic!("expected OSD map");
    };
    assert_eq!(map.len(), 3);
    for (key, count) in [("region_handle", 2), ("position", 3), ("look_at", 3)] {
        let OSD::Array(array) = map.get(key).expect("terse map key") else {
            panic!("expected OSD array for {key}");
        };
        assert_eq!(array.len(), count);
    }
}

fn minutes_name() -> Expected {
    Expected::Map(vec![
        ("MINUTES", Expected::Integer(5)),
        ("NAME", Expected::String("Hippotropolis")),
    ])
}

// parity-case: LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeLLSDSample::test 2495e7d5c414b59962f03282c51fe1c0d5de350b51c1bdfcee9ced7c32acbe4d translated
#[test]
fn xml_deserialize_llsd_sample() {
    let input = r#"<?xml version='1.0' encoding='UTF-8'?>
            <llsd>
                <map>
	                <key>region_id</key>
	                <uuid>67153d5b-3659-afb4-8510-adda2c034649</uuid>
	                <key>scale</key>
	                <string>one minute</string>
	                <key>simulator statistics</key>
	                <map>
		                <key>time dilation</key>
		                <real>0.9878624</real>
		                <key>sim fps</key>
		                <real>44.38898</real>
		                <key>agent updates per second</key>
		                <real>nan</real>
		                <key>total task count</key>
		                <real>4</real>
		                <key>active task count</key>
		                <real>0</real>
		                <key>pending uploads</key>
		                <real>0.0001096525</real>
	                </map>
                </map>
            </llsd>"#;
    let actual = OSDParser::deserialize_llsd_xml_with_bytes(input.as_bytes().to_vec())
        .expect("OSDParser DeserializeLLSDXml sample");
    assert_osd(
        actual,
        &Expected::Map(vec![
            (
                "region_id",
                Expected::UuidValue("67153d5b-3659-afb4-8510-adda2c034649"),
            ),
            ("scale", Expected::String("one minute")),
            (
                "simulator statistics",
                Expected::Map(vec![
                    ("time dilation", Expected::Real(0.987_862_4)),
                    ("sim fps", Expected::Real(44.388_98)),
                    ("agent updates per second", Expected::Real(f64::NAN)),
                    ("total task count", Expected::Real(4.0)),
                    ("active task count", Expected::Real(0.0)),
                    ("pending uploads", Expected::Real(0.000_109_652_5)),
                ]),
            ),
        ]),
    );
}

// parity-case: LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeNoDTD::test 9bc25ce11695355a0b81622301db687495d414c9a293505f6d421f27ac24eb70 translated
#[test]
fn xml_deserialize_no_dtd() {
    let input = r#"<llsd>
            <map>
              <key>MINUTES</key>
              <integer>5</integer>
              <key>NAME</key>
              <string>Hippotropolis</string>
            </map>
            </llsd>"#;
    let actual = OSDParser::deserialize_llsd_xml_with_bytes(input.as_bytes().to_vec())
        .expect("OSDParser DeserializeLLSDXml without DTD");
    assert_osd(actual, &minutes_name());
}

// parity-case: LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeSillyPI::test 08f94779e33e1dff4bd88eb75c7e032947dfb75f9ac7b14432847e705f08176d translated
#[test]
fn xml_deserialize_silly_pi() {
    let input = r#"<? LLSD/XML ?>\n
            <llsd>
            <map>
              <key>MINUTES</key>
              <integer>5</integer>
              <key>NAME</key>
              <string>Hippotropolis</string>
            </map>
            </llsd>\n"#;
    let actual = OSDParser::deserialize_llsd_xml_with_bytes(input.as_bytes().to_vec())
        .expect("OSDParser DeserializeLLSDXml silly PI");
    assert_osd(actual, &minutes_name());
}

// parity-case: LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeSillyPI_NoWhitespaceAfterPI::test 931129de5766458c7dc9ebefd5c1a8a8eeefd04715703c2997ff7da0d67f4bca translated
#[test]
fn xml_deserialize_silly_pi_no_whitespace_after_pi() {
    let input = "<? LLSD/XML ?><llsd>\n<map>\n  <key>MINUTES</key>\n  <integer>5</integer>\n  <key>NAME</key>\n  <string>Hippotropolis</string>\n</map>\n</llsd>\n";
    let actual = OSDParser::deserialize_llsd_xml_with_bytes(input.as_bytes().to_vec())
        .expect("OSDParser DeserializeLLSDXml PI without whitespace");
    assert_osd(actual, &minutes_name());
}

// parity-case: LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeSillyPI_LowercasePI::test 6a041c98c805419ed16b0caf3c249054be9f3f0fcc5884abd6b2ece2f23cf72d translated
#[test]
fn xml_deserialize_silly_pi_lowercase_pi() {
    let input = "<? llsd/xml ?>\n<llsd>\n<map>\n  <key>MINUTES</key>\n  <integer>5</integer>\n  <key>NAME</key>\n  <string>Hippotropolis</string>\n</map>\n</llsd>\n";
    let actual = OSDParser::deserialize_llsd_xml_with_bytes(input.as_bytes().to_vec())
        .expect("OSDParser DeserializeLLSDXml lowercase PI");
    assert_osd(actual, &minutes_name());
}

// parity-case: LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeReals::test c1e1db52fb2c1f023376d40b795461767f573555ddd4b4372182345bf99164e0 translated
#[test]
fn xml_deserialize_reals() {
    let input = r#"<?xml version='1.0' encoding='UTF-8'?>
            <llsd>
                <array>
                    <real>44.38898</real>
		            <real>nan</real>
		            <real>4</real>
                    <real>-13.333</real>
                    <real/>
                </array>
            </llsd>"#;
    let expected = Expected::Array(vec![
        Expected::Real(44.388_98),
        Expected::Real(f64::NAN),
        Expected::Real(4.0),
        Expected::Real(-13.333),
        Expected::Real(0.0),
    ]);
    let actual = OSDParser::deserialize_llsd_xml_with_bytes(input.as_bytes().to_vec())
        .expect("OSDParser DeserializeLLSDXml reals");
    assert_osd(actual, &expected);
}

// parity-case: LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeStrings::test e2b49b6bfbaecd26243fbcaa93abe48a340f4203c88aad874f2aef83f169baed translated
#[test]
fn xml_deserialize_strings() {
    let input = r#"<?xml version='1.0' encoding='UTF-8'?>
            <llsd>
                <array>
                    <string>Kissling</string>
                    <string>Attack ships on fire off the shoulder of Orion</string>
                    <string>&lt; &gt; &amp; &apos; &quot;</string>
                    <string/>
                </array>
            </llsd>"#;
    let expected = Expected::Array(vec![
        Expected::String("Kissling"),
        Expected::String("Attack ships on fire off the shoulder of Orion"),
        Expected::String("< > & ' \""),
        Expected::String(""),
    ]);
    let actual = OSDParser::deserialize_llsd_xml_with_bytes(input.as_bytes().to_vec())
        .expect("OSDParser DeserializeLLSDXml strings");
    assert_osd(actual, &expected);
}

// parity-case: LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeIntegers::test 281793a4a04cecd610065a70d0d3b54ad62fd2d6cc614b476d07f69d83c3dcb9 translated
#[test]
fn xml_deserialize_integers() {
    let input = r#"<?xml version='1.0' encoding='UTF-8'?>
            <llsd>
                <array>
                    <integer>2147483647</integer>
		            <integer>-2147483648</integer>
		            <integer>0</integer>
                    <integer>013</integer>
                    <integer/>
                </array>
            </llsd>"#;
    let expected = Expected::Array(vec![
        Expected::Integer(i32::MAX),
        Expected::Integer(i32::MIN),
        Expected::Integer(0),
        Expected::Integer(13),
        Expected::Integer(0),
    ]);
    let actual = OSDParser::deserialize_llsd_xml_with_bytes(input.as_bytes().to_vec())
        .expect("OSDParser DeserializeLLSDXml integers");
    assert_osd(actual, &expected);
}

// parity-case: LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeUUID::test bd2d0c2d4e583931174355724d948a0dbf6e79ec8fe907048f627b013a43bbea translated
#[test]
fn xml_deserialize_uuid() {
    let input = r#"<?xml version='1.0' encoding='UTF-8'?>
            <llsd>
                <array>
                    <uuid>d7f4aeca-88f1-42a1-b385-b9db18abb255</uuid>
                    <uuid/>
                </array>
            </llsd>"#;
    let expected = Expected::Array(vec![
        Expected::UuidValue("d7f4aeca-88f1-42a1-b385-b9db18abb255"),
        Expected::UuidValue("00000000-0000-0000-0000-000000000000"),
    ]);
    let actual = OSDParser::deserialize_llsd_xml_with_bytes(input.as_bytes().to_vec())
        .expect("OSDParser DeserializeLLSDXml UUIDs");
    assert_osd(actual, &expected);
}

// parity-case: LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeDates::test 55507ef1bf9d7749d05c4941f645d37a48b4c9f16dda10b05a7e73673ee2be33 translated
#[test]
fn xml_deserialize_dates() {
    let input = r#"<?xml version='1.0' encoding='UTF-8'?>
            <llsd>
                <array>
                    <date>2006-02-01T14:29:53Z</date>
                    <date>1999-01-01T00:00:00Z</date>
                    <date/>
                </array>
            </llsd>"#;
    let actual = OSDParser::deserialize_llsd_xml_with_bytes(input.as_bytes().to_vec())
        .expect("OSDParser DeserializeLLSDXml dates");
    let expected = Expected::Array(vec![
        Expected::Date(utc(1_138_804_193, 0)),
        Expected::Date(utc(915_148_800, 0)),
        Expected::Date(Utils::epoch()),
    ]);
    assert_osd(actual, &expected);
}

// parity-case: LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeBoolean::test 0f3d00c5f93b9f8d13938c77dd791dac4b8b093db926c164d92a3dd9bd38e741 translated
#[test]
fn xml_deserialize_boolean() {
    let input = r#"<?xml version='1.0' encoding='UTF-8'?>
            <llsd>
                <array>
                    <boolean>1</boolean>
                    <boolean>true</boolean>
                    <boolean>0</boolean>
                    <boolean>false</boolean>
                    <boolean/>
                </array>
            </llsd>"#;
    let expected = Expected::Array(vec![
        Expected::Bool(true),
        Expected::Bool(true),
        Expected::Bool(false),
        Expected::Bool(false),
        Expected::Bool(false),
    ]);
    let actual = OSDParser::deserialize_llsd_xml_with_bytes(input.as_bytes().to_vec())
        .expect("OSDParser DeserializeLLSDXml booleans");
    assert_osd(actual, &expected);
}

const XML_RANDOM: &[u8] = &[114, 97, 110, 100, 111, 109];
const XML_QUICK_BROWN_FOX: &[u8] = &[
    116, 104, 101, 32, 113, 117, 105, 99, 107, 32, 98, 114, 111, 119, 110, 32, 102, 111, 120,
];

// parity-case: LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeBinary::test f6c61bed3a3e6d97b203006e42a6c7b7b131aee08712ad4974f34d2e221e3ff9 translated
#[test]
fn xml_deserialize_binary() {
    let input = r#"<?xml version='1.0' encoding='UTF-8'?>
            <llsd>
                <array>
                    <binary encoding='base64'>cmFuZG9t</binary>
                    <binary>dGhlIHF1aWNrIGJyb3duIGZveA==</binary>
                    <binary/>
                </array>
            </llsd>"#;
    let expected = Expected::Array(vec![
        Expected::Binary(XML_RANDOM),
        Expected::Binary(XML_QUICK_BROWN_FOX),
        Expected::Binary(&[]),
    ]);
    let actual = OSDParser::deserialize_llsd_xml_with_bytes(input.as_bytes().to_vec())
        .expect("OSDParser DeserializeLLSDXml binary values");
    assert_osd(actual, &expected);
}

// parity-case: LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeUndef::test 45991c825d7d4f758c9650362df499e2f0afb079cc68f81973b5cd1eb704184c translated
#[test]
fn xml_deserialize_undef() {
    let input = r#"<?xml version='1.0' encoding='UTF-8'?>
            <llsd>
                <undef/>
            </llsd>"#;
    let _actual = OSDParser::deserialize_llsd_xml_with_bytes(input.as_bytes().to_vec())
        .expect("OSDParser DeserializeLLSDXml undef");
}

// parity-case: LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeURI::test da322601509a3520b8ee2c303396f0d13a86a38727ce39ad043b9bc48d2302bf translated
#[test]
fn xml_deserialize_uri() {
    let input = r#"<?xml version='1.0' encoding='UTF-8'?>
            <llsd>
                <array>
                    <uri>http://sim956.agni.lindenlab.com:12035/runtime/agents</uri>
                    <uri/>
                </array>
            </llsd>"#;
    let expected = Expected::Array(vec![
        Expected::Uri("http://sim956.agni.lindenlab.com:12035/runtime/agents"),
        Expected::Uri(""),
    ]);
    let actual = OSDParser::deserialize_llsd_xml_with_bytes(input.as_bytes().to_vec())
        .expect("OSDParser DeserializeLLSDXml URIs");
    assert_osd(actual, &expected);
}

// parity-case: LibreMetaverse.Tests/XmlLLSDTests.cs::XmlSDTests.DeserializeNestedContainers::test d0100e0e1f1de74a6060199f0cc7d4f94c745f073fadf8333b4eff51fd08af0a translated
#[test]
fn xml_deserialize_nested_containers() {
    let input = r#"<?xml version='1.0' encoding='UTF-8'?>
            <llsd>
                <array>
                    <map>
                        <key>Map One</key>
                        <map>
                            <key>Array One</key>
                            <array>
                                <integer>1</integer>
                                <integer>2</integer>
                            </array>
                        </map>
                    </map>
                    <array>
                        <string>A</string>
                        <string>B</string>
                        <array>
                            <integer>1</integer>
                            <integer>4</integer>
                            <integer>9</integer>
                        </array>
                    </array>
                </array>
            </llsd>"#;
    let actual = OSDParser::deserialize_llsd_xml_with_bytes(input.as_bytes().to_vec())
        .expect("OSDParser DeserializeLLSDXml");
    let OSD::Array(mut top) = actual else {
        panic!("expected top-level OSD array");
    };
    assert_eq!(top.len(), 2);
    let OSD::Map(mut first) = top.remove(0) else {
        panic!("expected first OSD map");
    };
    let OSD::Map(mut nested_map) = first.remove("Map One").expect("Map One") else {
        panic!("expected nested OSD map");
    };
    let OSD::Array(nested_array) = nested_map.remove("Array One").expect("Array One") else {
        panic!("expected first nested OSD array");
    };
    assert_eq!(nested_array.len(), 2);
    let OSD::Array(second) = top.remove(0) else {
        panic!("expected second OSD array");
    };
    assert_eq!(second.len(), 3);
    let OSD::Array(last) = second.into_iter().nth(2).expect("last nested array") else {
        panic!("expected last nested OSD array");
    };
    assert_eq!(last.len(), 3);
}
