Skip to content

Commit e94fce8

Browse files
committed
move to common
1 parent 999e81b commit e94fce8

File tree

2 files changed

+48
-32
lines changed

2 files changed

+48
-32
lines changed

common/src/table.rs

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use std::cell::{RefCell, RefMut};
2-
use std::collections::HashMap;
2+
use std::collections::{HashMap, BTreeSet};
33
use std::iter::zip;
44
use std::ops::Index;
55

66
use taplo::syntax::SyntaxKind::{ENTRY, IDENT, KEY, NEWLINE, TABLE_ARRAY_HEADER, TABLE_HEADER, VALUE};
77
use taplo::syntax::{SyntaxElement, SyntaxNode};
88
use taplo::HashSet;
9+
use taplo::{dom::node::DomNode as _, parser::parse};
910

1011
use crate::create::{make_empty_newline, make_key, make_newline, make_table_entry};
1112
use crate::string::load_text;
@@ -296,6 +297,14 @@ pub fn collapse_sub_tables(tables: &mut Tables, name: &str, exclude: &[Vec<Strin
296297
if main_positions.len() != 1 {
297298
return;
298299
}
300+
301+
// remove `name` from `exclude`s (and skip if `name` is not a prefix)
302+
let prefix = parse_ident(name).expect("could not parse prefix");
303+
let exclude: BTreeSet<_> = exclude.into_iter().filter_map(|id| {
304+
let (prefix_2, rest) = id.split_at(prefix.len()+1);
305+
(prefix == prefix_2).then_some(rest)
306+
}).collect();
307+
299308
let mut main = tables.table_set[*main_positions.first().unwrap()].borrow_mut();
300309
for key in sub_table_keys {
301310
let sub_positions = tables.header_to_pos[key].clone();
@@ -340,3 +349,35 @@ pub fn collapse_sub_tables(tables: &mut Tables, name: &str, exclude: &[Vec<Strin
340349
sub.clear();
341350
}
342351
}
352+
353+
pub fn parse_ident(ident: &str) -> Result<Vec<String>, String> {
354+
let parsed = parse(&format!("{ident} = 1"));
355+
if let Some(e) = parsed.errors.first() {
356+
return Err(format!("syntax error: {e}"));
357+
}
358+
359+
let root = parsed.into_dom();
360+
let errors = root.errors();
361+
if let Some(e) = errors.get().first() {
362+
return Err(format!("semantic error: {e}"));
363+
}
364+
365+
dbg!(&root.errors());
366+
367+
// We cannot use `.into_syntax()` since only the DOM transformation
368+
// allows accessing ident `.value()`s without quotes.
369+
let mut node = root;
370+
let mut parts = vec![];
371+
while let Ok(table) = node.try_into_table() {
372+
let entries = table.entries().get();
373+
if entries.len() != 1 {
374+
return Err("expected exactly one entry".to_string());
375+
}
376+
let mut it = entries.iter();
377+
let (key, next_node) = it.next().unwrap(); // checked if len == 1 above
378+
379+
parts.push(key.value().to_string());
380+
node = next_node.clone();
381+
}
382+
Ok(parts)
383+
}

pyproject-fmt/rust/src/main.rs

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
use std::string::String;
2-
use std::vec;
32

4-
use common::taplo::dom::node::DomNode;
53
use common::taplo::formatter::{format_syntax, Options};
64
use common::taplo::parser::parse;
75
use pyo3::exceptions::PyValueError;
@@ -102,36 +100,13 @@ pub fn format_toml(content: &str, opt: &Settings) -> String {
102100
format_syntax(root_ast, options)
103101
}
104102

103+
/// Parse a nested toml identifier into a tuple of idents
104+
///
105+
/// >>> parse_ident('a."b.c"')
106+
/// ('a', 'b.c')
105107
#[pyfunction]
106-
pub fn parse_ident<'py>(py: pyo3::Python<'py>, ident: String) -> PyResult<Bound<'py, PyTuple>> {
107-
let parsed = parse(&format!("{ident} = 1"));
108-
if let Some(e) = parsed.errors.first() {
109-
return Err(PyValueError::new_err(format!("syntax error: {e}")));
110-
}
111-
112-
let root = parsed.into_dom();
113-
let errors = root.errors();
114-
if let Some(e) = errors.get().first() {
115-
return Err(PyValueError::new_err(format!("semantic error: {e}")));
116-
}
117-
118-
dbg!(&root.errors());
119-
120-
// We cannot use `.into_syntax()` since only the DOM transformation
121-
// allows accessing ident `.value()`s without quotes.
122-
let mut node = root;
123-
let mut parts = vec![];
124-
while let Ok(table) = node.try_into_table() {
125-
let entries = table.entries().get();
126-
if entries.len() != 1 {
127-
return Err(PyValueError::new_err("expected exactly one entry"));
128-
}
129-
let mut it = entries.iter();
130-
let (key, next_node) = it.next().unwrap(); // checked if len == 1 above
131-
132-
parts.push(key.value().to_string());
133-
node = next_node.clone();
134-
}
108+
pub fn parse_ident<'py>(py: pyo3::Python<'py>, ident: &str) -> PyResult<Bound<'py, PyTuple>> {
109+
let parts = common::table::parse_ident(ident).map_err(|e| PyValueError::new_err(e))?;
135110
PyTuple::new(py, parts)
136111
}
137112

0 commit comments

Comments
 (0)