chore(snix): s/tvix/snix/
Change-Id: Iae961416eea0a38bc57df7b736f6dda5903b0828
This commit is contained in:
parent
768f053416
commit
36e4d017f5
1417 changed files with 3741 additions and 3650 deletions
24
snix/nix-compat-derive-tests/Cargo.toml
Normal file
24
snix/nix-compat-derive-tests/Cargo.toml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
[package]
|
||||
name = "nix-compat-derive-tests"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[features]
|
||||
compile-tests = []
|
||||
|
||||
[dev-dependencies]
|
||||
hex-literal.workspace = true
|
||||
pretty_assertions.workspace = true
|
||||
rstest.workspace = true
|
||||
tokio-test.workspace = true
|
||||
trybuild.workspace = true
|
||||
tokio = { workspace = true, features = ["io-util", "macros"] }
|
||||
|
||||
[dev-dependencies.nix-compat]
|
||||
version = "0.1.0"
|
||||
path = "../nix-compat"
|
||||
features = ["test", "wire"]
|
||||
|
||||
[dev-dependencies.nix-compat-derive]
|
||||
version = "0.1.0"
|
||||
path = "../nix-compat-derive"
|
||||
5
snix/nix-compat-derive-tests/default.nix
Normal file
5
snix/nix-compat-derive-tests/default.nix
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{ depot, ... }:
|
||||
|
||||
depot.snix.crates.workspaceMembers.nix-compat-derive-tests.build.override {
|
||||
runTests = true;
|
||||
}
|
||||
476
snix/nix-compat-derive-tests/tests/read_derive.rs
Normal file
476
snix/nix-compat-derive-tests/tests/read_derive.rs
Normal file
|
|
@ -0,0 +1,476 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use nix_compat::wire::de::mock::{Builder, Error};
|
||||
use nix_compat::wire::de::NixRead;
|
||||
use nix_compat_derive::NixDeserialize;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixDeserialize)]
|
||||
pub struct UnitTest;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixDeserialize)]
|
||||
pub struct EmptyTupleTest();
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixDeserialize)]
|
||||
pub struct StructTest {
|
||||
first: u64,
|
||||
second: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixDeserialize)]
|
||||
pub struct TupleTest(u64, String);
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixDeserialize)]
|
||||
pub struct StructVersionTest {
|
||||
test: u64,
|
||||
#[nix(version = "20..")]
|
||||
hello: String,
|
||||
}
|
||||
|
||||
fn default_test() -> StructVersionTest {
|
||||
StructVersionTest {
|
||||
test: 89,
|
||||
hello: String::from("klomp"),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixDeserialize)]
|
||||
pub struct TupleVersionTest(u64, #[nix(version = "25..")] String);
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixDeserialize)]
|
||||
pub struct TupleVersionDefaultTest(
|
||||
u64,
|
||||
#[nix(version = "..25", default = "default_test")] StructVersionTest,
|
||||
);
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_unit() {
|
||||
let mut mock = Builder::new().build();
|
||||
let v: UnitTest = mock.read_value().await.unwrap();
|
||||
assert_eq!(UnitTest, v);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_empty_tuple() {
|
||||
let mut mock = Builder::new().build();
|
||||
let v: EmptyTupleTest = mock.read_value().await.unwrap();
|
||||
assert_eq!(EmptyTupleTest(), v);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_struct() {
|
||||
let mut mock = Builder::new().read_number(89).read_slice(b"klomp").build();
|
||||
let v: StructTest = mock.read_value().await.unwrap();
|
||||
assert_eq!(
|
||||
StructTest {
|
||||
first: 89,
|
||||
second: String::from("klomp"),
|
||||
},
|
||||
v
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_tuple() {
|
||||
let mut mock = Builder::new().read_number(89).read_slice(b"klomp").build();
|
||||
let v: TupleTest = mock.read_value().await.unwrap();
|
||||
assert_eq!(TupleTest(89, String::from("klomp")), v);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_struct_version() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 20))
|
||||
.read_number(89)
|
||||
.read_slice(b"klomp")
|
||||
.build();
|
||||
let v: StructVersionTest = mock.read_value().await.unwrap();
|
||||
assert_eq!(default_test(), v);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_struct_without_version() {
|
||||
let mut mock = Builder::new().version((1, 19)).read_number(89).build();
|
||||
let v: StructVersionTest = mock.read_value().await.unwrap();
|
||||
assert_eq!(
|
||||
StructVersionTest {
|
||||
test: 89,
|
||||
hello: String::new(),
|
||||
},
|
||||
v
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_tuple_version() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 26))
|
||||
.read_number(89)
|
||||
.read_slice(b"klomp")
|
||||
.build();
|
||||
let v: TupleVersionTest = mock.read_value().await.unwrap();
|
||||
assert_eq!(TupleVersionTest(89, "klomp".into()), v);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_tuple_without_version() {
|
||||
let mut mock = Builder::new().version((1, 19)).read_number(89).build();
|
||||
let v: TupleVersionTest = mock.read_value().await.unwrap();
|
||||
assert_eq!(TupleVersionTest(89, String::new()), v);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_complex_1() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 19))
|
||||
.read_number(999)
|
||||
.read_number(666)
|
||||
.build();
|
||||
let v: TupleVersionDefaultTest = mock.read_value().await.unwrap();
|
||||
assert_eq!(
|
||||
TupleVersionDefaultTest(
|
||||
999,
|
||||
StructVersionTest {
|
||||
test: 666,
|
||||
hello: String::new()
|
||||
}
|
||||
),
|
||||
v
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_complex_2() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 20))
|
||||
.read_number(999)
|
||||
.read_number(666)
|
||||
.read_slice(b"The quick brown \xF0\x9F\xA6\x8A jumps over 13 lazy \xF0\x9F\x90\xB6.")
|
||||
.build();
|
||||
let v: TupleVersionDefaultTest = mock.read_value().await.unwrap();
|
||||
assert_eq!(
|
||||
TupleVersionDefaultTest(
|
||||
999,
|
||||
StructVersionTest {
|
||||
test: 666,
|
||||
hello: String::from("The quick brown 🦊 jumps over 13 lazy 🐶.")
|
||||
}
|
||||
),
|
||||
v
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_complex_3() {
|
||||
let mut mock = Builder::new().version((1, 25)).read_number(999).build();
|
||||
let v: TupleVersionDefaultTest = mock.read_value().await.unwrap();
|
||||
assert_eq!(
|
||||
TupleVersionDefaultTest(
|
||||
999,
|
||||
StructVersionTest {
|
||||
test: 89,
|
||||
hello: String::from("klomp")
|
||||
}
|
||||
),
|
||||
v
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_complex_4() {
|
||||
let mut mock = Builder::new().version((1, 26)).read_number(999).build();
|
||||
let v: TupleVersionDefaultTest = mock.read_value().await.unwrap();
|
||||
assert_eq!(
|
||||
TupleVersionDefaultTest(
|
||||
999,
|
||||
StructVersionTest {
|
||||
test: 89,
|
||||
hello: String::from("klomp")
|
||||
}
|
||||
),
|
||||
v
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_field_invalid_data() {
|
||||
let mut mock = Builder::new()
|
||||
.read_number(666)
|
||||
.read_slice(b"The quick brown \xED\xA0\x80 jumped.")
|
||||
.build();
|
||||
let err = mock.read_value::<StructTest>().await.unwrap_err();
|
||||
assert_eq!(
|
||||
Error::InvalidData("invalid utf-8 sequence of 1 bytes from index 16".into()),
|
||||
err
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_field_missing_data() {
|
||||
let mut mock = Builder::new().read_number(666).build();
|
||||
let err = mock.read_value::<StructTest>().await.unwrap_err();
|
||||
assert_eq!(Error::MissingData("unexpected end-of-file".into()), err);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_field_no_data() {
|
||||
let mut mock = Builder::new().build();
|
||||
let err = mock.read_value::<StructTest>().await.unwrap_err();
|
||||
assert_eq!(Error::MissingData("unexpected end-of-file".into()), err);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_field_reader_error_first() {
|
||||
let mut mock = Builder::new()
|
||||
.read_number_error(Error::InvalidData("Bad reader".into()))
|
||||
.build();
|
||||
let err = mock.read_value::<StructTest>().await.unwrap_err();
|
||||
assert_eq!(Error::InvalidData("Bad reader".into()), err);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_field_reader_error_later() {
|
||||
let mut mock = Builder::new()
|
||||
.read_number(999)
|
||||
.read_bytes_error(Error::InvalidData("Bad reader".into()))
|
||||
.build();
|
||||
let err = mock.read_value::<StructTest>().await.unwrap_err();
|
||||
assert_eq!(Error::InvalidData("Bad reader".into()), err);
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixDeserialize)]
|
||||
#[nix(from_str)]
|
||||
struct TestFromStr;
|
||||
|
||||
impl FromStr for TestFromStr {
|
||||
type Err = String;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if s == "test" {
|
||||
Ok(TestFromStr)
|
||||
} else {
|
||||
Err(s.into())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_from_str() {
|
||||
let mut mock = Builder::new().read_slice(b"test").build();
|
||||
let value = mock.read_value::<TestFromStr>().await.unwrap();
|
||||
assert_eq!(TestFromStr, value);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_from_str_invalid_data() {
|
||||
let mut mock = Builder::new().read_slice(b"wrong string").build();
|
||||
let err = mock.read_value::<TestFromStr>().await.unwrap_err();
|
||||
assert_eq!(Error::InvalidData("wrong string".into()), err);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_from_str_invalid_string() {
|
||||
let mut mock = Builder::new()
|
||||
.read_slice(b"The quick brown \xED\xA0\x80 jumped.")
|
||||
.build();
|
||||
let err = mock.read_value::<TestFromStr>().await.unwrap_err();
|
||||
assert_eq!(
|
||||
Error::InvalidData("invalid utf-8 sequence of 1 bytes from index 16".into()),
|
||||
err
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_from_str_reader_error() {
|
||||
let mut mock = Builder::new()
|
||||
.read_bytes_error(Error::InvalidData("Bad reader".into()))
|
||||
.build();
|
||||
let err = mock.read_value::<TestFromStr>().await.unwrap_err();
|
||||
assert_eq!(Error::InvalidData("Bad reader".into()), err);
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixDeserialize)]
|
||||
#[nix(try_from = "u64")]
|
||||
struct TestTryFromU64;
|
||||
|
||||
impl TryFrom<u64> for TestTryFromU64 {
|
||||
type Error = u64;
|
||||
|
||||
fn try_from(value: u64) -> Result<TestTryFromU64, Self::Error> {
|
||||
if value == 42 {
|
||||
Ok(TestTryFromU64)
|
||||
} else {
|
||||
Err(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_try_from_u64() {
|
||||
let mut mock = Builder::new().read_number(42).build();
|
||||
let value = mock.read_value::<TestTryFromU64>().await.unwrap();
|
||||
assert_eq!(TestTryFromU64, value);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_try_from_u64_invalid_data() {
|
||||
let mut mock = Builder::new().read_number(666).build();
|
||||
let err = mock.read_value::<TestTryFromU64>().await.unwrap_err();
|
||||
assert_eq!(Error::InvalidData("666".into()), err);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_try_from_u64_reader_error() {
|
||||
let mut mock = Builder::new()
|
||||
.read_number_error(Error::InvalidData("Bad reader".into()))
|
||||
.build();
|
||||
let err = mock.read_value::<TestTryFromU64>().await.unwrap_err();
|
||||
assert_eq!(Error::InvalidData("Bad reader".into()), err);
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixDeserialize)]
|
||||
#[nix(from = "u64")]
|
||||
struct TestFromU64;
|
||||
|
||||
impl From<u64> for TestFromU64 {
|
||||
fn from(_value: u64) -> TestFromU64 {
|
||||
TestFromU64
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_from_u64() {
|
||||
let mut mock = Builder::new().read_number(42).build();
|
||||
let value = mock.read_value::<TestFromU64>().await.unwrap();
|
||||
assert_eq!(TestFromU64, value);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_from_u64_reader_error() {
|
||||
let mut mock = Builder::new()
|
||||
.read_number_error(Error::InvalidData("Bad reader".into()))
|
||||
.build();
|
||||
let err = mock.read_value::<TestFromU64>().await.unwrap_err();
|
||||
assert_eq!(Error::InvalidData("Bad reader".into()), err);
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixDeserialize)]
|
||||
enum TestEnum {
|
||||
#[nix(version = "..=19")]
|
||||
Pre20(TestTryFromU64, #[nix(version = "10..")] u64),
|
||||
#[nix(version = "20..=29")]
|
||||
Post20(StructVersionTest),
|
||||
#[nix(version = "30..=39")]
|
||||
Post30,
|
||||
#[nix(version = "40..")]
|
||||
Post40 {
|
||||
msg: String,
|
||||
#[nix(version = "45..")]
|
||||
level: u64,
|
||||
},
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_enum_9() {
|
||||
let mut mock = Builder::new().version((1, 9)).read_number(42).build();
|
||||
let value = mock.read_value::<TestEnum>().await.unwrap();
|
||||
assert_eq!(TestEnum::Pre20(TestTryFromU64, 0), value);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_enum_19() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 19))
|
||||
.read_number(42)
|
||||
.read_number(666)
|
||||
.build();
|
||||
let value = mock.read_value::<TestEnum>().await.unwrap();
|
||||
assert_eq!(TestEnum::Pre20(TestTryFromU64, 666), value);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_enum_20() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 20))
|
||||
.read_number(42)
|
||||
.read_slice(b"klomp")
|
||||
.build();
|
||||
let value = mock.read_value::<TestEnum>().await.unwrap();
|
||||
assert_eq!(
|
||||
TestEnum::Post20(StructVersionTest {
|
||||
test: 42,
|
||||
hello: "klomp".into(),
|
||||
}),
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_enum_30() {
|
||||
let mut mock = Builder::new().version((1, 30)).build();
|
||||
let value = mock.read_value::<TestEnum>().await.unwrap();
|
||||
assert_eq!(TestEnum::Post30, value);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_enum_40() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 40))
|
||||
.read_slice(b"hello world")
|
||||
.build();
|
||||
let value = mock.read_value::<TestEnum>().await.unwrap();
|
||||
assert_eq!(
|
||||
TestEnum::Post40 {
|
||||
msg: "hello world".into(),
|
||||
level: 0,
|
||||
},
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_enum_45() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 45))
|
||||
.read_slice(b"hello world")
|
||||
.read_number(9001)
|
||||
.build();
|
||||
let value = mock.read_value::<TestEnum>().await.unwrap();
|
||||
assert_eq!(
|
||||
TestEnum::Post40 {
|
||||
msg: "hello world".into(),
|
||||
level: 9001,
|
||||
},
|
||||
value
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_enum_reader_error() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 19))
|
||||
.read_number_error(Error::InvalidData("Bad reader".into()))
|
||||
.build();
|
||||
let err = mock.read_value::<TestEnum>().await.unwrap_err();
|
||||
assert_eq!(Error::InvalidData("Bad reader".into()), err);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_enum_invalid_data_9() {
|
||||
let mut mock = Builder::new().version((1, 9)).read_number(666).build();
|
||||
let err = mock.read_value::<TestEnum>().await.unwrap_err();
|
||||
assert_eq!(Error::InvalidData("666".into()), err);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn read_enum_invalid_data_20() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 20))
|
||||
.read_number(666)
|
||||
.read_slice(b"The quick brown \xED\xA0\x80 jumped.")
|
||||
.build();
|
||||
let err = mock.read_value::<TestEnum>().await.unwrap_err();
|
||||
assert_eq!(
|
||||
Error::InvalidData("invalid utf-8 sequence of 1 bytes from index 16".into()),
|
||||
err
|
||||
);
|
||||
}
|
||||
6
snix/nix-compat-derive-tests/tests/ui.rs
Normal file
6
snix/nix-compat-derive-tests/tests/ui.rs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#[cfg(feature = "compile-tests")]
|
||||
#[test]
|
||||
fn ui() {
|
||||
let t = trybuild::TestCases::new();
|
||||
t.compile_fail("tests/ui/*.rs");
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
use nix_compat_derive::NixDeserialize;
|
||||
|
||||
pub struct BadType;
|
||||
|
||||
#[derive(NixDeserialize)]
|
||||
pub struct Test {
|
||||
version: BadType,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
error[E0277]: the trait bound `BadType: NixDeserialize` is not satisfied
|
||||
--> tests/ui/deserialize_bad_type.rs:7:14
|
||||
|
|
||||
7 | version: BadType,
|
||||
| ^^^^^^^ the trait `NixDeserialize` is not implemented for `BadType`
|
||||
|
|
||||
= help: the following other types implement trait `NixDeserialize`:
|
||||
BTreeMap<K, V>
|
||||
ClientSettings
|
||||
IgnoredZero
|
||||
Operation
|
||||
StorePath<String>
|
||||
String
|
||||
Test
|
||||
Vec<T>
|
||||
and $N others
|
||||
note: required by a bound in `try_read_value`
|
||||
--> $WORKSPACE/nix-compat/src/wire/de/mod.rs
|
||||
|
|
||||
| fn try_read_value<V: NixDeserialize>(
|
||||
| ^^^^^^^^^^^^^^ required by this bound in `NixRead::try_read_value`
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
use nix_compat_derive::NixDeserialize;
|
||||
|
||||
#[derive(NixDeserialize)]
|
||||
pub enum Test {
|
||||
#[nix(version = "..=10")]
|
||||
Old,
|
||||
#[nix(version = "15..=17")]
|
||||
Legacy,
|
||||
#[nix(version = "50..")]
|
||||
NewWay,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
error[E0004]: non-exhaustive patterns: `11_u8..=14_u8` and `18_u8..=49_u8` not covered
|
||||
--> tests/ui/deserialize_enum_non_exaustive.rs:3:10
|
||||
|
|
||||
3 | #[derive(NixDeserialize)]
|
||||
| ^^^^^^^^^^^^^^ patterns `11_u8..=14_u8` and `18_u8..=49_u8` not covered
|
||||
|
|
||||
= note: the matched value is of type `u8`
|
||||
= note: this error originates in the derive macro `NixDeserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
use nix_compat_derive::NixDeserialize;
|
||||
|
||||
#[derive(NixDeserialize)]
|
||||
#[nix(from = "u64")]
|
||||
pub struct Test;
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
error[E0277]: the trait bound `Test: From<u64>` is not satisfied
|
||||
--> tests/ui/deserialize_from_missing.rs:4:14
|
||||
|
|
||||
4 | #[nix(from = "u64")]
|
||||
| ^^^^^ the trait `From<u64>` is not implemented for `Test`
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use nix_compat_derive::NixDeserialize;
|
||||
|
||||
#[derive(NixDeserialize)]
|
||||
#[nix(from_str)]
|
||||
pub struct Test;
|
||||
|
||||
impl FromStr for Test {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if s == "test" {
|
||||
Ok(Test)
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
error[E0277]: `()` doesn't implement `std::fmt::Display`
|
||||
--> tests/ui/deserialize_from_str_error_not_display.rs:6:7
|
||||
|
|
||||
6 | #[nix(from_str)]
|
||||
| ^^^^^^^^ `()` cannot be formatted with the default formatter
|
||||
|
|
||||
= help: the trait `std::fmt::Display` is not implemented for `()`
|
||||
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
|
||||
note: required by a bound in `invalid_data`
|
||||
--> $WORKSPACE/nix-compat/src/wire/de/mod.rs
|
||||
|
|
||||
| fn invalid_data<T: fmt::Display>(msg: T) -> Self {
|
||||
| ^^^^^^^^^^^^ required by this bound in `Error::invalid_data`
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
use nix_compat_derive::NixDeserialize;
|
||||
|
||||
#[derive(NixDeserialize)]
|
||||
#[nix(from_str)]
|
||||
pub struct Test;
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
error[E0277]: the trait bound `Test: FromStr` is not satisfied
|
||||
--> tests/ui/deserialize_from_str_missing.rs:4:7
|
||||
|
|
||||
4 | #[nix(from_str)]
|
||||
| ^^^^^^^^ the trait `FromStr` is not implemented for `Test`
|
||||
|
|
||||
= help: the following other types implement trait `FromStr`:
|
||||
IpAddr
|
||||
Ipv4Addr
|
||||
Ipv6Addr
|
||||
NonZero<i128>
|
||||
NonZero<i16>
|
||||
NonZero<i32>
|
||||
NonZero<i64>
|
||||
NonZero<i8>
|
||||
and $N others
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
use nix_compat_derive::NixDeserialize;
|
||||
|
||||
#[derive(NixDeserialize)]
|
||||
pub struct Value(String);
|
||||
|
||||
#[derive(NixDeserialize)]
|
||||
pub struct Test {
|
||||
#[nix(version = "20..")]
|
||||
version: Value,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
error[E0277]: the trait bound `Value: Default` is not satisfied
|
||||
--> tests/ui/deserialize_missing_default.rs:6:10
|
||||
|
|
||||
6 | #[derive(NixDeserialize)]
|
||||
| ^^^^^^^^^^^^^^ the trait `Default` is not implemented for `Value`
|
||||
|
|
||||
= note: this error originates in the derive macro `NixDeserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider annotating `Value` with `#[derive(Default)]`
|
||||
|
|
||||
4 + #[derive(Default)]
|
||||
5 | pub struct Value(String);
|
||||
|
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
use nix_compat_derive::NixDeserialize;
|
||||
|
||||
#[derive(NixDeserialize)]
|
||||
pub struct Value(String);
|
||||
|
||||
#[derive(NixDeserialize)]
|
||||
pub struct Test {
|
||||
#[nix(version = "20..", default = "Value::make_default")]
|
||||
version: Value,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
error[E0599]: no function or associated item named `make_default` found for struct `Value` in the current scope
|
||||
--> tests/ui/deserialize_missing_default_path.rs:8:39
|
||||
|
|
||||
4 | pub struct Value(String);
|
||||
| ---------------- function or associated item `make_default` not found for this struct
|
||||
...
|
||||
8 | #[nix(version = "20..", default = "Value::make_default")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^ function or associated item not found in `Value`
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
use nix_compat_derive::nix_deserialize_remote;
|
||||
|
||||
pub struct Value(String);
|
||||
impl From<String> for Value {
|
||||
fn from(s: String) -> Value {
|
||||
Value(s)
|
||||
}
|
||||
}
|
||||
|
||||
nix_deserialize_remote!(
|
||||
#[nix()]
|
||||
Value
|
||||
);
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
error: Missing from_str, from or try_from attribute
|
||||
--> tests/ui/deserialize_remote_missing_attr.rs:11:5
|
||||
|
|
||||
11 | / #[nix()]
|
||||
12 | | Value
|
||||
| |_________^
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
use nix_compat_derive::NixDeserialize;
|
||||
|
||||
#[derive(NixDeserialize)]
|
||||
#[nix(try_from = "u64")]
|
||||
pub struct Test;
|
||||
|
||||
impl TryFrom<u64> for Test {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: u64) -> Result<Test, Self::Error> {
|
||||
if value == 42 {
|
||||
Ok(Test)
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
error[E0277]: `()` doesn't implement `std::fmt::Display`
|
||||
--> tests/ui/deserialize_try_from_error_not_display.rs:4:18
|
||||
|
|
||||
4 | #[nix(try_from = "u64")]
|
||||
| ^^^^^ `()` cannot be formatted with the default formatter
|
||||
|
|
||||
= help: the trait `std::fmt::Display` is not implemented for `()`
|
||||
= note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
|
||||
note: required by a bound in `invalid_data`
|
||||
--> $WORKSPACE/nix-compat/src/wire/de/mod.rs
|
||||
|
|
||||
| fn invalid_data<T: fmt::Display>(msg: T) -> Self {
|
||||
| ^^^^^^^^^^^^ required by this bound in `Error::invalid_data`
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
use nix_compat_derive::NixDeserialize;
|
||||
|
||||
#[derive(NixDeserialize)]
|
||||
#[nix(try_from = "u64")]
|
||||
pub struct Test;
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
error[E0277]: the trait bound `Test: From<u64>` is not satisfied
|
||||
--> tests/ui/deserialize_try_from_missing.rs:4:18
|
||||
|
|
||||
4 | #[nix(try_from = "u64")]
|
||||
| ^^^^^ the trait `From<u64>` is not implemented for `Test`, which is required by `Test: TryFrom<u64>`
|
||||
|
|
||||
= note: required for `u64` to implement `Into<Test>`
|
||||
= note: required for `Test` to implement `TryFrom<u64>`
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
use nix_compat_derive::NixDeserialize;
|
||||
|
||||
#[derive(NixDeserialize)]
|
||||
pub struct Test {
|
||||
#[nix(default = 12)]
|
||||
version: u8,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
error: expected nix attribute default to be string
|
||||
--> tests/ui/parse_bad_default.rs:5:21
|
||||
|
|
||||
5 | #[nix(default = 12)]
|
||||
| ^^
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
use nix_compat_derive::NixDeserialize;
|
||||
|
||||
#[derive(NixDeserialize)]
|
||||
pub struct Test {
|
||||
#[nix(default = "12")]
|
||||
version: u8,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
error: expected identifier
|
||||
--> tests/ui/parse_bad_default_path.rs:5:21
|
||||
|
|
||||
5 | #[nix(default = "12")]
|
||||
| ^^^^
|
||||
9
snix/nix-compat-derive-tests/tests/ui/parse_bad_nix.rs
Normal file
9
snix/nix-compat-derive-tests/tests/ui/parse_bad_nix.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
use nix_compat_derive::NixDeserialize;
|
||||
|
||||
#[derive(NixDeserialize)]
|
||||
pub struct Test {
|
||||
#[nix]
|
||||
version: u8,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
error: expected attribute arguments in parentheses: #[nix(...)]
|
||||
--> tests/ui/parse_bad_nix.rs:5:7
|
||||
|
|
||||
5 | #[nix]
|
||||
| ^^^
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
use nix_compat_derive::NixDeserialize;
|
||||
|
||||
#[derive(NixDeserialize)]
|
||||
pub struct Test {
|
||||
#[nix(version = 12)]
|
||||
version: u8,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
error: expected nix attribute version to be string
|
||||
--> tests/ui/parse_bad_version.rs:5:21
|
||||
|
|
||||
5 | #[nix(version = 12)]
|
||||
| ^^
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
use nix_compat_derive::NixDeserialize;
|
||||
|
||||
#[derive(NixDeserialize)]
|
||||
pub struct Test {
|
||||
#[nix(version)]
|
||||
version: u8,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
error: expected `=`
|
||||
--> tests/ui/parse_mising_version.rs:5:18
|
||||
|
|
||||
5 | #[nix(version)]
|
||||
| ^
|
||||
370
snix/nix-compat-derive-tests/tests/write_derive.rs
Normal file
370
snix/nix-compat-derive-tests/tests/write_derive.rs
Normal file
|
|
@ -0,0 +1,370 @@
|
|||
use std::fmt;
|
||||
|
||||
use nix_compat::wire::ser::{
|
||||
mock::{Builder, Error},
|
||||
NixWrite as _,
|
||||
};
|
||||
use nix_compat_derive::NixSerialize;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixSerialize)]
|
||||
pub struct UnitTest;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixSerialize)]
|
||||
pub struct EmptyTupleTest();
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixSerialize)]
|
||||
pub struct StructTest {
|
||||
first: u64,
|
||||
second: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixSerialize)]
|
||||
pub struct TupleTest(u64, String);
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixSerialize)]
|
||||
pub struct StructVersionTest {
|
||||
test: u64,
|
||||
#[nix(version = "20..")]
|
||||
hello: String,
|
||||
}
|
||||
|
||||
fn default_test() -> StructVersionTest {
|
||||
StructVersionTest {
|
||||
test: 89,
|
||||
hello: String::from("klomp"),
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixSerialize)]
|
||||
pub struct TupleVersionTest(u64, #[nix(version = "25..")] String);
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixSerialize)]
|
||||
pub struct TupleVersionDefaultTest(u64, #[nix(version = "..25")] StructVersionTest);
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_unit() {
|
||||
let mut mock = Builder::new().build();
|
||||
mock.write_value(&UnitTest).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_empty_tuple() {
|
||||
let mut mock = Builder::new().build();
|
||||
mock.write_value(&EmptyTupleTest()).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_struct() {
|
||||
let mut mock = Builder::new()
|
||||
.write_number(89)
|
||||
.write_slice(b"klomp")
|
||||
.build();
|
||||
mock.write_value(&StructTest {
|
||||
first: 89,
|
||||
second: String::from("klomp"),
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_tuple() {
|
||||
let mut mock = Builder::new()
|
||||
.write_number(89)
|
||||
.write_slice(b"klomp")
|
||||
.build();
|
||||
mock.write_value(&TupleTest(89, String::from("klomp")))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_struct_version() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 20))
|
||||
.write_number(89)
|
||||
.write_slice(b"klomp")
|
||||
.build();
|
||||
mock.write_value(&default_test()).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_struct_without_version() {
|
||||
let mut mock = Builder::new().version((1, 19)).write_number(89).build();
|
||||
mock.write_value(&StructVersionTest {
|
||||
test: 89,
|
||||
hello: String::new(),
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_tuple_version() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 26))
|
||||
.write_number(89)
|
||||
.write_slice(b"klomp")
|
||||
.build();
|
||||
mock.write_value(&TupleVersionTest(89, "klomp".into()))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_tuple_without_version() {
|
||||
let mut mock = Builder::new().version((1, 19)).write_number(89).build();
|
||||
mock.write_value(&TupleVersionTest(89, String::new()))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_complex_1() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 19))
|
||||
.write_number(999)
|
||||
.write_number(666)
|
||||
.build();
|
||||
mock.write_value(&TupleVersionDefaultTest(
|
||||
999,
|
||||
StructVersionTest {
|
||||
test: 666,
|
||||
hello: String::new(),
|
||||
},
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_complex_2() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 20))
|
||||
.write_number(999)
|
||||
.write_number(666)
|
||||
.write_slice(b"The quick brown \xF0\x9F\xA6\x8A jumps over 13 lazy \xF0\x9F\x90\xB6.")
|
||||
.build();
|
||||
mock.write_value(&TupleVersionDefaultTest(
|
||||
999,
|
||||
StructVersionTest {
|
||||
test: 666,
|
||||
hello: String::from("The quick brown 🦊 jumps over 13 lazy 🐶."),
|
||||
},
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_complex_3() {
|
||||
let mut mock = Builder::new().version((1, 25)).write_number(999).build();
|
||||
mock.write_value(&TupleVersionDefaultTest(
|
||||
999,
|
||||
StructVersionTest {
|
||||
test: 89,
|
||||
hello: String::from("klomp"),
|
||||
},
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_complex_4() {
|
||||
let mut mock = Builder::new().version((1, 26)).write_number(999).build();
|
||||
mock.write_value(&TupleVersionDefaultTest(
|
||||
999,
|
||||
StructVersionTest {
|
||||
test: 89,
|
||||
hello: String::from("klomp"),
|
||||
},
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixSerialize)]
|
||||
#[nix(display)]
|
||||
struct TestFromStr;
|
||||
|
||||
impl fmt::Display for TestFromStr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "test")
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_display() {
|
||||
let mut mock = Builder::new().write_display("test").build();
|
||||
mock.write_value(&TestFromStr).await.unwrap();
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixSerialize)]
|
||||
#[nix(display = "TestFromStr2::display")]
|
||||
struct TestFromStr2;
|
||||
struct TestFromStrDisplay;
|
||||
|
||||
impl fmt::Display for TestFromStrDisplay {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "test")
|
||||
}
|
||||
}
|
||||
impl TestFromStr2 {
|
||||
fn display(&self) -> TestFromStrDisplay {
|
||||
TestFromStrDisplay
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_display_path() {
|
||||
let mut mock = Builder::new().write_display("test").build();
|
||||
mock.write_value(&TestFromStr2).await.unwrap();
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, NixSerialize)]
|
||||
#[nix(try_into = "u64")]
|
||||
struct TestTryFromU64(u64);
|
||||
|
||||
impl TryFrom<TestTryFromU64> for u64 {
|
||||
type Error = u64;
|
||||
|
||||
fn try_from(value: TestTryFromU64) -> Result<Self, Self::Error> {
|
||||
if value.0 != 42 {
|
||||
Ok(value.0)
|
||||
} else {
|
||||
Err(value.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_try_into_u64() {
|
||||
let mut mock = Builder::new().write_number(666).build();
|
||||
mock.write_value(&TestTryFromU64(666)).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_try_into_u64_invalid_data() {
|
||||
let mut mock = Builder::new().build();
|
||||
let err = mock.write_value(&TestTryFromU64(42)).await.unwrap_err();
|
||||
assert_eq!(Error::UnsupportedData("42".into()), err);
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, NixSerialize)]
|
||||
#[nix(into = "u64")]
|
||||
struct TestFromU64;
|
||||
|
||||
impl From<TestFromU64> for u64 {
|
||||
fn from(_value: TestFromU64) -> u64 {
|
||||
42
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_into_u64() {
|
||||
let mut mock = Builder::new().write_number(42).build();
|
||||
mock.write_value(&TestFromU64).await.unwrap();
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, NixSerialize)]
|
||||
enum TestEnum {
|
||||
#[nix(version = "..=19")]
|
||||
Pre20(TestFromU64, #[nix(version = "10..")] u64),
|
||||
#[nix(version = "20..=29")]
|
||||
Post20(StructVersionTest),
|
||||
#[nix(version = "30..=39")]
|
||||
Post30,
|
||||
#[nix(version = "40..")]
|
||||
Post40 {
|
||||
msg: String,
|
||||
#[nix(version = "45..")]
|
||||
level: u64,
|
||||
},
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_enum_9() {
|
||||
let mut mock = Builder::new().version((1, 9)).write_number(42).build();
|
||||
mock.write_value(&TestEnum::Pre20(TestFromU64, 666))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_enum_19() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 19))
|
||||
.write_number(42)
|
||||
.write_number(666)
|
||||
.build();
|
||||
mock.write_value(&TestEnum::Pre20(TestFromU64, 666))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_enum_20() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 20))
|
||||
.write_number(666)
|
||||
.write_slice(b"klomp")
|
||||
.build();
|
||||
mock.write_value(&TestEnum::Post20(StructVersionTest {
|
||||
test: 666,
|
||||
hello: "klomp".into(),
|
||||
}))
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_enum_30() {
|
||||
let mut mock = Builder::new().version((1, 30)).build();
|
||||
mock.write_value(&TestEnum::Post30).await.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_enum_40() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 40))
|
||||
.write_slice(b"hello world")
|
||||
.build();
|
||||
mock.write_value(&TestEnum::Post40 {
|
||||
msg: "hello world".into(),
|
||||
level: 9001,
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_enum_45() {
|
||||
let mut mock = Builder::new()
|
||||
.version((1, 45))
|
||||
.write_slice(b"hello world")
|
||||
.write_number(9001)
|
||||
.build();
|
||||
mock.write_value(&TestEnum::Post40 {
|
||||
msg: "hello world".into(),
|
||||
level: 9001,
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn write_wrong_enum() {
|
||||
let mut mock = Builder::new().version((1, 30)).build();
|
||||
let err = mock
|
||||
.write_value(&TestEnum::Post40 {
|
||||
msg: "hello world".into(),
|
||||
level: 9001,
|
||||
})
|
||||
.await
|
||||
.unwrap_err();
|
||||
assert_eq!(
|
||||
err,
|
||||
Error::InvalidEnum("Post40 is not valid for version 1.30".into())
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue