On 11/13/2011 11:53 PM, David Rajchenbach-Teller wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1Dear Rusties, I am currently in the early stages of writing a file system access library for mozilla-central that might eventually replace some or all of mozilla-central low-level file access code with something faster and a little higher level. I also consider porting ? perhaps even prototyping ? this library to Rust. For this purpose, I need a little guidance on a few points. *** #ifdef My code heavily relies on #ifdefs with macros to compile code conditionally, depending on both: - - which platform is targeted (in mozilla-central, that's macros XP_WIN, XP_UNIX); - - which primitives are available in libc (through autoconf's AC_CHECK_FUNS and the macros HAVE_xxxxx that it defines). What is the best way to achieve this in Rust?
Rust items can be conditionally compiled with the 'cfg' attribute, so your build can call 'rustc --cfg FEATURE' (and you can provide --cfg any number of times) then you can have functions annotated #[cfg(FEATURE)]. The target platform is already set by default as 'target_os', so you can say #[cfg(target_os = "win32")].
If your question is more about how to integrate your autoconf-based build with Rust's anti-autoconf build then the answer is probably that they have to be kept separate.
*** Foreign types - From what I see in the code of unix_os.rs, we can simply define `type foobar` in a foreign module and use this in the code. Are there any limitations to this that I should know before employing the technique?
These types are pointer sized, so they can be used to pass around pointers to opaque types, but not much else. If that doesn't work then you have to create a Rust declaration with the same structure as the C declaration. std does this in a few places.
*** Unicode On Unix platforms, file names are `char*`. On Windows platforms, they are `wchar*`. In mozilla-central, I use the strings API to make my life simpler and to handle all conversions for me. How should I do this with Rust? As far as I understand, the current win32_os.rs simply assumes that any `str` passed can be used as a valid `char*`, and relies on Cygwin to handle any oddity. As most of the features of Win32 are not available through Cygwin, this is probably something that I cannot use.
stdlib's string handling for win32 is wrong and I don't believe anybody has put much thought into what needs to happen. Suggestions welcome.
*** Garbage-collection / destruction I am not familiar with Rust resources yet, but chances are that I will need to interact with them to get destruction and garbage-collection on file descriptors and directory structures. - - Do I understand correctly that resources a the right tool for the task? - - From the documentation, I understand that a failed task will not call destructors. Do I understand correctly? If so, this seems like a major issue, as a process with failed tasks will leak file descriptors.
Resources are what you want, but you usually want to box them and wrap them in some other type because they are a bit unwieldy from a user perspective. Failed tasks will call destructors during unwinding. Can you point me to the incorrect documentation? One thing to note is that we still don't implement unwinding on win32 so failure is currently unrecoverable on that platform.
*** Error-handling For file access, some error conditions are indeed failures, while some are simply information that should be propagated. As I understand, Rust will not have ML/C++-style exceptions in any foreseeable future. I therefore see the following possibilities: - - Either aggressively `spawn_notify` tasks, `unsupervise` them and `fail` in case of any error, with some convention to pass `errno`;
I've tried to implement this approach before and found that the language is not yet expressive enough to do this in a convenient way (because we can't spawn closures). It's also quite inefficient for general use.
- - or have each function return `either::t<Result, Error>` and propagate error conditions manually, much as is done in current mozilla-central code;
std has a 'result::t<T, U>' type that I am trying to use for this purpose. std::io makes use of this now.
- - or offer both styles, with some naming convention to differentiate them ? say submodules `fails` / `dnf`. Any suggestion on the best policy?
I prefer std::result
Well, that covers most of my interrogations. Any suggestion or idea?
Sounds promising. _______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
