Skip to content
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

GString refactor #600

Merged
merged 14 commits into from
Dec 24, 2022
Merged

GString refactor #600

merged 14 commits into from
Dec 24, 2022

Conversation

jf2048
Copy link
Member

@jf2048 jf2048 commented Mar 10, 2022

Update: See comment #600 (comment) for the general status of this PR.

Original comment: All of these TryFrom are panicking when they don't really need to. This is probably going to break some other things, I'd like to check this against gtk-rs and gstreamer-rs at least. Another option is to leave the panicking From traits in and also support TryFrom.

Also makes GString deref as a GStr

@jf2048 jf2048 mentioned this pull request Mar 10, 2022
@jf2048 jf2048 force-pushed the gstring-traits branch 2 times, most recently from cb4667d to 5cbef4c Compare March 10, 2022 18:19
@sdroege
Copy link
Member

sdroege commented Mar 11, 2022

Also needs to be updated with GStr bits if #595 is merged

It's merged :)

@jf2048 jf2048 force-pushed the gstring-traits branch 2 times, most recently from 6da3b98 to fe45283 Compare March 11, 2022 13:47
@jf2048 jf2048 changed the title WIP: glib: Use TryFrom for GString conversions WIP: glib: Update GString traits Mar 11, 2022
@jf2048
Copy link
Member Author

jf2048 commented Mar 11, 2022

@jf2048 jf2048 changed the title WIP: glib: Update GString traits glib: Update GString traits Mar 11, 2022
@jf2048 jf2048 marked this pull request as ready for review March 11, 2022 16:30
@sdroege
Copy link
Member

sdroege commented Mar 12, 2022

Next step: change all functions that take &str to instead take impl AsRef<GStr> or so to avoid all the unnecessary memory copies :)

@@ -617,10 +617,10 @@ impl AsRef<[u8]> for GString {
}

impl Deref for GString {
type Target = str;
type Target = GStr;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we should think about the advantages / disadvantages of this. What does a &GStr bring in comparison to just having a &str?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have functions taking GStr only?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not yet, see my other comments

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe better to use str for the time being until we make the switch then.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll take this out, but gtk-rs/gtk3-rs#739 and gtk-rs/gir#1327 can still be merged without this if you want. They don't break anything.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like a good idea regardless, yes. More future-proof.

glib/src/gstring.rs Outdated Show resolved Hide resolved
@jf2048 jf2048 force-pushed the gstring-traits branch 3 times, most recently from 9e2ca9c to b2d545a Compare March 13, 2022 15:38
@jf2048 jf2048 marked this pull request as draft March 13, 2022 15:41
@jf2048
Copy link
Member Author

jf2048 commented Mar 13, 2022

Now added impl Default for GString, and an unsafe GString::from_utf8_unchecked if someone wants to skip all the extra checking added by the TryFroms

@jf2048
Copy link
Member Author

jf2048 commented Mar 13, 2022

Next step: change all functions that take &str to instead take impl AsRef<GStr> or so to avoid all the unnecessary memory copies :)

That was my thought too. We can test it out later with some of the manually implemented functions, and then afterwards work it into gir.

@jf2048 jf2048 marked this pull request as ready for review March 13, 2022 18:48
glib/src/gstring.rs Outdated Show resolved Hide resolved
@bilelmoussaoui
Copy link
Member

While you are updating GString traits, maybe we should have Default impls here. See the gstreamer-rs PR for context

Copy link
Member

@sdroege sdroege left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems OK to me apart from that final comment

@sdroege
Copy link
Member

sdroege commented Mar 14, 2022

While you are updating GString traits, maybe we should have Default impls here. See the gstreamer-rs PR for context

It's here already

@sdroege
Copy link
Member

sdroege commented Nov 20, 2022

Looks generally nice to me. Are you aware of any drawbacks here or does it all seem nice to you?

Also this should probably get a change to gir at some point to

  • Use impl IntoGStr for transfer none
  • Use impl Into<GString> for transfer full
    parameters.

@jf2048 jf2048 force-pushed the gstring-traits branch 4 times, most recently from a938c6b to 51f87df Compare November 26, 2022 04:18
@jf2048 jf2048 force-pushed the gstring-traits branch 2 times, most recently from bf3d2f1 to f984f68 Compare December 12, 2022 01:24
@jf2048
Copy link
Member Author

jf2048 commented Dec 12, 2022

Some drawbacks that still persist:

  • Unfortunate that it is not possible anymore to safely convert from GStr to CStr without re-scanning the string. But I think it is more "Rusty" to make paying that cost optional.
  • Still have to check all strings coming from C for valid UTF-8. No way to fix that right now as C has no real guarantees about strings.
  • The previously mentioned issue with needing None::<&str> or GStr::NONE.
  • There are a ton of GString constructors and error types now, could be confusing. Not sure if all are strictly necessary but in any case it was trivial to implement them in terms of each other.
  • The Inline variant is limited to 22 chars, it could be optimized further to hold an additional byte with some unsafe hackery to combine the length (5 bits) and the discriminant (2 bits).

@jf2048
Copy link
Member Author

jf2048 commented Dec 13, 2022

I think those issues are all design issues or can be fixed later, so this is ready now IMO

For consistency with str::as_bytes. Since we always store the length of
the slice we can always do a const conversion like str does.
Optimizes GString to avoid unnecessary checking for interior nul bytes.
Interior nul bytes will now only be checked upon request. When
converting to C strings, the string will always get truncated to the
first nul byte. Since GString can now contain interior nul bytes in some
circumstances, its interior representation is now Option<Box<str>>.

Also adds custom error types for conversions.
For const std::slice::from_raw_parts, stabilized in
rust-lang/rust#97522
Also use Cow<[u8]> as storage to optimize out empty string allocations.
add some PartialEq and PartialOrd implementations for GStr too
These traits can accept both &str or &GStr as an argument. A copy is
made when passing &str, but avoided when passing &GStr.
@sdroege sdroege merged commit 8a9d3be into gtk-rs:master Dec 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Panic if GString contains null byte
5 participants