Output a file to a buffer instead of the working copy. This is useful for testing, previewing, or cases where you want the content in memory rather than written to disk. # Arguments `txn` - Transaction providing graph access `changes` - Change store for retrieving span content `position` - Position in the graph `options` - Output options # Returns A tuple of (content bytes, conflicts). # Err
(
txn: &T,
changes: &C,
position: Position<NodeId>,
options: FileOutputOptions,
)
| 754 | /// println!("File content:\n{}", text); |
| 755 | /// ``` |
| 756 | pub fn output_file_to_buffer<T, C>( |
| 757 | txn: &T, |
| 758 | changes: &C, |
| 759 | position: Position<NodeId>, |
| 760 | options: FileOutputOptions, |
| 761 | ) -> Result<(Vec<u8>, Vec<FileConflict>), OutputError> |
| 762 | where |
| 763 | T: GraphTxnT, |
| 764 | C: ChangeStore, |
| 765 | { |
| 766 | // Retrieve the alive graph |
| 767 | let retrieve_opts = options.to_retrieve_options(); |
| 768 | let retrieve_result = retrieve_graph(txn, position, retrieve_opts) |
| 769 | .map_err(|e| OutputError::Pristine(Box::new(e)))?; |
| 770 | |
| 771 | // Handle empty graph |
| 772 | if retrieve_result.graph.is_empty() { |
| 773 | return Ok((Vec::new(), Vec::new())); |
| 774 | } |
| 775 | |
| 776 | // Compute SCC ordering |
| 777 | let mut graph = retrieve_result.graph; |
| 778 | let order = compute_order(&mut graph); |
| 779 | |
| 780 | // Create buffer writer |
| 781 | let buffer = Vec::new(); |
| 782 | let mut writer = Writer::new(buffer); |
| 783 | |
| 784 | // Hash function to convert NodeId to Hash using the transaction. |
| 785 | // This is required for the ChangeStore to load the correct change file |
| 786 | // and retrieve the content bytes for each span. |
| 787 | let hash_fn = |node_id: NodeId| -> Option<Hash> { |
| 788 | // Handle ROOT node - it has no hash |
| 789 | if node_id.is_root() { |
| 790 | return None; |
| 791 | } |
| 792 | // Use transaction's get_external to convert NodeId to Hash |
| 793 | txn.get_external(node_id).ok().flatten() |
| 794 | }; |
| 795 | |
| 796 | // Attempt semantic merge for any conflicting SCCs |
| 797 | let resolved = resolve_conflicts_semantically(txn, changes, &graph, &order); |
| 798 | |
| 799 | // Output the graph content (with semantic merge resolution) |
| 800 | output_graph_content_resolved(changes, hash_fn, &graph, &order, &mut writer, &resolved)?; |
| 801 | |
| 802 | // Extract buffer |
| 803 | let content = writer.into_inner(); |
| 804 | |
| 805 | // Extract conflicts from cyclic SCCs (only those NOT resolved by semantic merge) |
| 806 | let mut conflicts = Vec::new(); |
| 807 | let mut conflict_id: u32 = 0; |
| 808 | for scc in &order.sccs { |
| 809 | if scc.len() > 1 && resolved.get_merged(scc[0]).is_none() { |
| 810 | conflict_id += 1; |
| 811 | conflicts.push( |
| 812 | FileConflict::new(String::new(), FileConflictType::Cyclic).with_id(conflict_id), |
| 813 | ); |
no test coverage detected