MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / merge_items_into_section

Function merge_items_into_section

atomic-agent/src/learnings.rs:526–602  ·  view source on GitHub ↗

Merge new items into existing section headings without duplicating headings. If `### Repo` already exists in the section, new repo items are appended under the existing heading. If a heading doesn't exist yet, it's created.

(
    existing_content: &str,
    new_items: &HashMap<String, Vec<String>>,
)

Source from the content-addressed store, hash-verified

524/// If `### Repo` already exists in the section, new repo items are appended
525/// under the existing heading. If a heading doesn't exist yet, it's created.
526fn merge_items_into_section(
527 existing_content: &str,
528 new_items: &HashMap<String, Vec<String>>,
529) -> String {
530 let start_idx = match existing_content.find(SECTION_START) {
531 Some(idx) => idx + SECTION_START.len(),
532 None => return existing_content.to_string(),
533 };
534
535 let end_marker_idx = match existing_content[start_idx..].find(SECTION_END) {
536 Some(idx) => start_idx + idx,
537 None => return existing_content.to_string(),
538 };
539
540 let before_section = &existing_content[..start_idx];
541 let section_body = &existing_content[start_idx..end_marker_idx];
542 let after_section = &existing_content[end_marker_idx..];
543
544 // Parse existing section into heading → items
545 let mut sections: Vec<(String, Vec<String>)> = Vec::new();
546 let mut current_heading: Option<String> = None;
547 let mut current_items: Vec<String> = Vec::new();
548
549 for line in section_body.lines() {
550 let trimmed = line.trim();
551 if trimmed.starts_with("### ") {
552 // Save previous heading if any
553 if let Some(heading) = current_heading.take() {
554 sections.push((heading, std::mem::take(&mut current_items)));
555 }
556 current_heading = Some(trimmed.to_string());
557 } else if trimmed.starts_with("- ") {
558 current_items.push(trimmed.to_string());
559 }
560 }
561 if let Some(heading) = current_heading {
562 sections.push((heading, current_items));
563 }
564
565 // Merge new items into existing headings or append new headings
566 let mut merged_headings: std::collections::HashSet<String> = std::collections::HashSet::new();
567 for (heading, items) in sections.iter_mut() {
568 if let Some(new) = new_items.get(heading) {
569 items.extend(new.iter().cloned());
570 merged_headings.insert(heading.clone());
571 }
572 }
573
574 // Add headings that didn't exist yet
575 // Use a stable order: Repo first, then Workflow
576 for heading in &["### Repo", "### Workflow"] {
577 let heading = heading.to_string();
578 if !merged_headings.contains(&heading) {
579 if let Some(items) = new_items.get(&heading) {
580 sections.push((heading, items.clone()));
581 }
582 }
583 }

Calls 10

iter_mutMethod · 0.80
extendMethod · 0.80
getMethod · 0.65
lenMethod · 0.45
linesMethod · 0.45
pushMethod · 0.45
iterMethod · 0.45
insertMethod · 0.45
cloneMethod · 0.45
containsMethod · 0.45