-
Notifications
You must be signed in to change notification settings - Fork 307
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Port fontp to Rust #248
Port fontp to Rust #248
Conversation
rust_src/src/fonts.rs
Outdated
// See font_property_index in font.h for details. | ||
#[allow(non_camel_case_types, dead_code)] | ||
#[repr(C)] | ||
enum font_property_index { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This enum will probably want to be defined in the remacs-sys crate instead of here. That crate is where we house the code related to FFI and representing structures that are defined in the C layer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I will move it there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use camelcase names.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moved, with a new camelcase name.
rust_src/src/fonts.rs
Outdated
if v.is_pseudovector(PseudovecType::PVEC_FONT) { | ||
if extra_type.eq(Qnil) { | ||
LispObject::constant_t() | ||
} else if extra_type.eq(LispObject::from_raw(unsafe { Qfont_spec })) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I don't like the raw unsafe Q... usage here. Personally I like the idea of having safe methods implemented for LispObject like "is_font_spec", etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thoought it would be "safe enough" to get at these symbols this way -- is there another option?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me clarify:
Accessing these symbols the way you are doing is fine, but we have to use unsafe blocks in Lisp binding code. If we have another lisp binding that needs to do similar logic, we will need to add more unsafe blocks. In general, I think a Rust code base is at it's best when it minimizes unsafe code blocks.
We can improve this situation by adding a safe wrapper around unsafe code (since the code here is "unsafe" due to its interaction with C). For example something like:
impl LispObject {
pub fn is_font_spec(&self) -> bool {
self.eq(unsafe { /* ... */ });
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's fair. I think that fontp
is the only place that uses of Qfont_spec
and friends in this manner in the codebase, though. Is it worth writing a safe interface (for example, creating a FontEntity::from_object()
-style enum method)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a fair point, I'm personally fine either way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wrote a little enum to abstract this pattern out.
rust_src/src/fonts.rs
Outdated
} else { | ||
// As with the C version, checking that object is a font takes priority | ||
// over checking that extra_type is well-formed. | ||
Qnil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We generally prefer calls to LispObject::constant_nil() over raw Qnil usage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed.
Thanks for the contribution! This is looking good to me so far, I've left a few inline comments on a couple things I saw. |
Ok, I've added some |
I will probably wait on #244 before moving the struct to |
rust_src/src/fonts.rs
Outdated
#[lisp_fn(min = "1")] | ||
pub fn fontp(object: LispObject, extra_type: LispObject) -> LispObject { | ||
if object.is_font() { | ||
if extra_type.eq(LispObject::constant_nil()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shorter: extra_type.is_nil()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed.
rust_src/src/lisp.rs
Outdated
@@ -559,6 +560,27 @@ impl LispObject { | |||
v.is_pseudovector(PseudovecType::PVEC_FONT) | |||
}) | |||
} | |||
|
|||
pub fn is_font_spec(self) -> bool { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of adding these to LispObject
, I would create an as_font
method on is_vectorlike
that returns a "LispFontRef" or similar.
is_spec
, is_entity
etc can the be methods on that struct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I've taken this approach.
rust_src/src/fonts.rs
Outdated
} | ||
|
||
impl FontExtraType { | ||
pub fn from_object_or_error(extra_type: LispObject) -> FontExtraType { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer from_symbol_or_error
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
rust_src/src/fonts.rs
Outdated
FontExtraType::Object | ||
} else { | ||
// TODO: This should actually be equivalent to | ||
// intern("font-extra-type"), not Qsymbolp. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to call intern
, you can add it to the imported functions in remacs-sys
. Signature should be straightforward.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This turns out to be more difficult than it first appears. See #255.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
@@ -1096,3 +1096,47 @@ extern "C" { | |||
nchars_return: *mut ptrdiff_t, | |||
) -> ptrdiff_t; | |||
} | |||
|
|||
/// Contains C definitions from the font.h header. | |||
pub mod font { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea to add some modules to structure this crate!
Can be updated to use |
Signed-off-by: Aaron Jacobs <atheriel@gmail.com>
Signed-off-by: Aaron Jacobs <atheriel@gmail.com>
Signed-off-by: Aaron Jacobs <atheriel@gmail.com>
Signed-off-by: Aaron Jacobs <atheriel@gmail.com>
Signed-off-by: Aaron Jacobs <atheriel@gmail.com>
Signed-off-by: Aaron Jacobs <atheriel@gmail.com>
Updated to use |
Nope, looks, good! |
use vectors::LispVectorlikeRef; | ||
|
||
// A font is not a type in and of itself, it's just a group of three kinds of | ||
// pseudovector. This newtype allows us to define methods that yield the actual |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be improved.
- plural of pseudovectors
- missing space between new and type.
- First you mention that a font is not a type and then you continue with "This new type"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm glad someone is reading the docstrings :) Not quite sure I agree about the plural -- a font is "one of three kinds of pseudovector", so fonts are "a group of three kinds of pseudovector". Might be wrong here, though.
The term "newtype" refers to the Rust pattern of struct X(Y)
. It's not a typo. A "font" does not have its own structure in the C code. It refers to three possible structs. Hence a font is not "a type in and of itself". It's just a label for a group of structures. So I'm not actually defining any structure here, I just want to add some methods to LispVectorlikeRef
-- hence the newtype.
This is my first pass at porting
fontp
to Rust, and should be considered a work in progress. I have a few questions:Should I change the naming convention for thefont_property_index
enum?Is there a convention for callingSee Adds intern and an intern_static! macro #255.intern
from Rust code?Can or should I addis_font_spec()
(etc) methods toLispObject
inlisp.rs
, so that the checking can be moved out offontp
and into those methods?This should close #233.