Skip to content

Commit 2315ce9

Browse files
String repr quote option from Ruff project
Co-Authored-By: Charlie Marsh <charlie.r.marsh@gmail.com>
1 parent f4b9bdf commit 2315ce9

File tree

2 files changed

+51
-17
lines changed

2 files changed

+51
-17
lines changed

common/src/bytes.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
use crate::str::ReprOverflowError;
1+
use crate::str::{Quote, ReprOverflowError};
22

3-
pub fn repr(b: &[u8]) -> Result<String, ReprOverflowError> {
4-
repr_with(b, &[], "")
3+
pub fn repr(b: &[u8], quote: Quote) -> Result<String, ReprOverflowError> {
4+
repr_with(b, &[], "", quote)
55
}
66

7-
pub fn repr_with(b: &[u8], prefixes: &[&str], suffix: &str) -> Result<String, ReprOverflowError> {
7+
pub fn repr_with(
8+
b: &[u8],
9+
prefixes: &[&str],
10+
suffix: &str,
11+
quote: Quote,
12+
) -> Result<String, ReprOverflowError> {
813
use std::fmt::Write;
914

1015
let mut out_len = 0usize;
@@ -28,7 +33,7 @@ pub fn repr_with(b: &[u8], prefixes: &[&str], suffix: &str) -> Result<String, Re
2833
out_len = out_len.checked_add(incr).ok_or(ReprOverflowError)?;
2934
}
3035

31-
let (quote, num_escaped_quotes) = crate::str::choose_quotes_for_repr(squote, dquote);
36+
let (quote, num_escaped_quotes) = crate::str::choose_quotes_for_repr(squote, dquote, quote);
3237
// we'll be adding backslashes in front of the existing inner quotes
3338
out_len += num_escaped_quotes;
3439

common/src/str.rs

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ use std::{
99
ops::{Bound, RangeBounds},
1010
};
1111

12+
#[derive(Debug, Clone, Copy)]
13+
pub enum Quote {
14+
Single,
15+
Double,
16+
}
17+
1218
#[cfg(not(target_arch = "wasm32"))]
1319
#[allow(non_camel_case_types)]
1420
pub type wchar_t = libc::wchar_t;
@@ -344,9 +350,10 @@ macro_rules! ascii {
344350

345351
/// Get a Display-able type that formats to the python `repr()` of the string value
346352
#[inline]
347-
pub fn repr(s: &str) -> Repr<'_> {
353+
pub fn repr(s: &str, quote: Quote) -> Repr<'_> {
348354
Repr {
349355
s,
356+
quote,
350357
info: OnceCell::new(),
351358
}
352359
}
@@ -365,8 +372,9 @@ struct ReprInfo {
365372
dquoted: bool,
366373
out_len: usize,
367374
}
375+
368376
impl ReprInfo {
369-
fn get(s: &str) -> Result<Self, ReprOverflowError> {
377+
fn get(s: &str, default_quote: Quote) -> Result<Self, ReprOverflowError> {
370378
let mut out_len = 0usize;
371379
let mut squote = 0;
372380
let mut dquote = 0;
@@ -398,7 +406,7 @@ impl ReprInfo {
398406
}
399407
}
400408

401-
let (quote, num_escaped_quotes) = choose_quotes_for_repr(squote, dquote);
409+
let (quote, num_escaped_quotes) = choose_quotes_for_repr(squote, dquote, default_quote);
402410
// we'll be adding backslashes in front of the existing inner quotes
403411
out_len += num_escaped_quotes;
404412

@@ -413,12 +421,15 @@ impl ReprInfo {
413421

414422
pub struct Repr<'a> {
415423
s: &'a str,
424+
// the quote type we prefer to use
425+
quote: Quote,
416426
// the tuple is dquouted, out_len
417427
info: OnceCell<Result<ReprInfo, ReprOverflowError>>,
418428
}
429+
419430
impl Repr<'_> {
420431
fn get_info(&self) -> Result<ReprInfo, ReprOverflowError> {
421-
*self.info.get_or_init(|| ReprInfo::get(self.s))
432+
*self.info.get_or_init(|| ReprInfo::get(self.s, self.quote))
422433
}
423434

424435
/// Same as `<Self as ToString>::to_string()`, but checks for a possible OverflowError.
@@ -483,14 +494,32 @@ impl fmt::Display for Repr<'_> {
483494
}
484495
}
485496

486-
/// returns the outer quotes to use and the number of quotes that need to be escaped
487-
pub(crate) fn choose_quotes_for_repr(num_squotes: usize, num_dquotes: usize) -> (char, usize) {
488-
// always use squote unless we have squotes but no dquotes
489-
let use_dquote = num_squotes > 0 && num_dquotes == 0;
490-
if use_dquote {
491-
('"', num_dquotes)
492-
} else {
493-
('\'', num_squotes)
497+
/// Returns the outer quotes to use and the number of quotes that need to be
498+
/// escaped.
499+
pub(crate) const fn choose_quotes_for_repr(
500+
num_squotes: usize,
501+
num_dquotes: usize,
502+
quote: Quote,
503+
) -> (char, usize) {
504+
match quote {
505+
Quote::Single => {
506+
// always use squote unless we have squotes but no dquotes
507+
let use_dquote = num_squotes > 0 && num_dquotes == 0;
508+
if use_dquote {
509+
('"', num_dquotes)
510+
} else {
511+
('\'', num_squotes)
512+
}
513+
}
514+
Quote::Double => {
515+
// always use dquote unless we have dquotes but no squotes
516+
let use_squote = num_dquotes > 0 && num_squotes == 0;
517+
if use_squote {
518+
('\'', num_squotes)
519+
} else {
520+
('"', num_dquotes)
521+
}
522+
}
494523
}
495524
}
496525

0 commit comments

Comments
 (0)