use vize_carton::{String, ToCompactString};
use super::string_tracking::{
compact_render_body, count_braces_with_state, count_parens_with_state, StringTrackState,
};
pub(crate) fn extract_template_parts_full(template_code: &str) -> (String, String, String) {
let mut imports = String::default();
let mut hoisted = String::default();
let mut render_fn = String::default();
let mut in_render = false;
let mut brace_depth = 0;
let mut brace_state = StringTrackState::default();
for line in template_code.lines() {
let trimmed = line.trim();
if trimmed.starts_with("import ") {
imports.push_str(line);
imports.push('\n');
} else if trimmed.starts_with("const _hoisted_") {
hoisted.push_str(line);
hoisted.push('\n');
} else if trimmed.starts_with("export function render(")
|| trimmed.starts_with("function render(")
{
in_render = true;
brace_depth = 0;
brace_state = StringTrackState::default();
brace_depth += count_braces_with_state(line, &mut brace_state);
render_fn.push_str(line);
render_fn.push('\n');
} else if in_render {
brace_depth += count_braces_with_state(line, &mut brace_state);
render_fn.push_str(line);
render_fn.push('\n');
if brace_depth == 0 {
in_render = false;
}
}
}
(imports, hoisted, render_fn)
}
#[allow(dead_code)]
pub(crate) fn extract_template_parts(template_code: &str) -> (String, String, String, String) {
let mut imports = String::default();
let mut hoisted = String::default();
let mut preamble = String::default(); let mut render_body = String::default();
let mut in_render = false;
let mut in_return = false;
let mut brace_depth = 0;
let mut brace_state = StringTrackState::default();
let mut paren_state = StringTrackState::default();
let mut return_paren_depth = 0;
let lines: Vec<&str> = template_code.lines().collect();
for (i, line) in lines.iter().enumerate() {
let trimmed = line.trim();
if trimmed.starts_with("import ") {
imports.push_str(line);
imports.push('\n');
} else if trimmed.starts_with("const _hoisted_") {
hoisted.push_str(line);
hoisted.push('\n');
} else if trimmed.starts_with("export function render(")
|| trimmed.starts_with("function render(")
{
in_render = true;
brace_depth = 0;
brace_state = StringTrackState::default();
paren_state = StringTrackState::default();
brace_depth += count_braces_with_state(line, &mut brace_state);
} else if in_render {
brace_depth += count_braces_with_state(line, &mut brace_state);
if in_return {
render_body.push('\n');
render_body.push_str(line);
return_paren_depth += count_parens_with_state(line, &mut paren_state);
if return_paren_depth <= 0 {
let next_continues_ternary = lines
.iter()
.skip(i + 1)
.map(|l| l.trim())
.find(|l| !l.is_empty())
.map(|l| l.starts_with('?') || l.starts_with(':'))
.unwrap_or(false);
if !next_continues_ternary {
in_return = false;
let trimmed_body = render_body.trim_end();
if let Some(stripped) = trimmed_body.strip_suffix(';') {
render_body = stripped.to_compact_string();
}
}
}
} else if let Some(stripped) = trimmed.strip_prefix("return ") {
render_body = stripped.to_compact_string();
paren_state = StringTrackState::default();
return_paren_depth = count_parens_with_state(stripped, &mut paren_state);
if return_paren_depth > 0 {
in_return = true;
} else {
let next_continues_ternary = lines
.iter()
.skip(i + 1)
.map(|l| l.trim())
.find(|l| !l.is_empty())
.map(|l| l.starts_with('?') || l.starts_with(':'))
.unwrap_or(false);
if next_continues_ternary {
in_return = true;
} else {
if render_body.ends_with(';') {
render_body.pop();
}
}
}
} else if trimmed.starts_with("const _component_")
|| trimmed.starts_with("const _directive_")
{
preamble.push_str(trimmed);
preamble.push('\n');
}
if brace_depth == 0 {
in_render = false;
}
}
}
let compacted = compact_render_body(&render_body);
(imports, hoisted, preamble, compacted)
}