Hi guys. I translate a script from D to Rust. You can check if everything is correct?
D Source file
Rust source file
First, one way you can replicate PAWN_CELL_SIZE
is like so:
macro_rules! PAWN_CELL_SIZE {
(16) => {
pub const PAWN_CELL_SIZE: usize = 16;
pub type cell = i16;
pub type ucell = u16;
};
(32) => {
pub const PAWN_CELL_SIZE: usize = 32;
pub type cell = i32;
pub type ucell = u32;
};
(64) => {
pub const PAWN_CELL_SIZE: usize = 64;
pub type cell = i64;
pub type ucell = u64;
};
}
PAWN_CELL_SIZE!(32);
Also, you can use #![allow(non_camel_case_types)]
at the top to disable the lint module- or crate-wide.
I believe your enum translation is wrong. Assuming I remember correctly, D allows you to store any value of the base type you want in an enum. Rust absolutely does not allow this. The closest you can currently get with Rust would be to have something like:
pub type AmxData = u32;
pub const USERNUM: AmxData = 4;
...
Or you can manually namespace the constants if you want:
pub type AmxData = u32;
#[allow(non_snake_case)]
pub mod AmxDataC {
use super::AmxData;
pub const USERNUM: AmxData = 4;
...
}
Your function pointers should all be Option<unsafe extern "C" fn (...) -> ...>
. Function pointers in Rust cannot be null, and unless you know for a fact that the callbacks will go into Rust code, you should also assume they're unsafe.
I'm not sure if you did it deliberately, but your translation of AmxDebug_fn
and AmxNative_fn
is both right and wrong. It's wrong in that a ref T
in D is mutable, whereas &T
in Rust is immutable. It's right in that ref T
in D is not &mut T
in Rust, because &mut T
in Rust cannot be aliased, whereas I believe it can in D. &T
can be aliased, but doesn't allow mutation.
I suspect the closest translation for ref T
would be &UnsafeCell<T>
... but I don't know if that's actually guaranteed or not. Unless someone can confirm that it is, you might be better off using *mut T
and noting in the code that it won't be null.
For Amx::usertags
, isn't D long
64-bit? If so, should be i64
in Rust.
I don't know if you're asking a question about AmxNativeInfo::name
. immutable
in D is const
in Rust. There's no equivalent to D's const
.
Again, more long
-> i32
. I just checked, and long
is 64-bit, so all long
-> i32
conversions are wrong.
You should be able to translate char
in D to u8
in Rust.
I just saw AmxTagInfo::name
. Ok, look... I think that will technically work, but you are not allowed to assume that. The layout of &str
is not guaranteed, so far as I know, so it could break at any time. It would be safer to write a type that represents a D string and just translates the fields into a Rust slice. Look up the Deref
trait, and std::slice::from_raw_parts
.
Oh! And D slices can be null, &str
cannot be null. So yeah, that translation is wrong.
Still, so close. Woulda been cool.
Again, another enum. D enums and Rust enums aren't the same.