mod cells;
mod error;
mod fill8949;
mod fill8949_full;
mod form1040;
mod form1040_full;
mod form8275;
mod form8283;
mod form8959;
mod form8960;
mod form8995;
mod map;
mod overflow;
mod packet;
mod pdf;
mod schedule23;
mod schedule_a;
mod schedule_b;
mod schedule_c;
mod schedule_d;
mod schedule_d_full;
mod schedule_se;
mod schedule_se_full;
mod transcribe;
mod verify;
mod watermark;
mod wrap;
pub use error::FormsError;
pub use form1040::{Form1040Fill, Form1040Inputs};
pub use form8275::PartIiCapacity;
pub use map::{
Form1040Map, Form8275Map, Form8283Map, Form8949Map, Form8959Map, Form8960Map, Form8995Map,
Schedule1Map, Schedule2Map, Schedule3Map, ScheduleAMap, ScheduleBMap, ScheduleCMap,
ScheduleDMap, ScheduleSeMap,
};
pub use schedule_se::SE_FLOOR;
pub use wrap::PartIiOverflow;
use btctax_core::conventions::{TaxDate, Usd};
use btctax_core::{Form8949Row, ScheduleDTotals};
use time::macros::format_description;
pub const SUPPORTED_YEARS: &[i32] = &[2017, 2024, 2025];
pub(crate) fn fmt_date(d: TaxDate) -> Result<String, FormsError> {
let fmt = format_description!("[month]/[day]/[year]");
d.format(&fmt)
.map_err(|e| FormsError::Structure(format!("date format: {e}")))
}
pub(crate) fn fmt_money(d: Usd) -> String {
d.to_string()
}
pub fn fill_form_8949(rows: &[Form8949Row], year: i32) -> Result<Vec<u8>, FormsError> {
let map = Form8949Map::for_year(year)?;
let cap = map.rows_per_page;
let (st, lt) = fill8949::split_parts(rows);
let n_pages = div_ceil(st.len(), cap).max(div_ceil(lt.len(), cap)).max(1);
if n_pages == 1 {
let short = fill8949::part_data(&st)?;
let long = fill8949::part_data(<)?;
return fill8949::fill_8949_parts(&short, &long, &map);
}
let mut copies = Vec::with_capacity(n_pages);
for k in 0..n_pages {
let st_chunk: Vec<&Form8949Row> = st.iter().skip(k * cap).take(cap).copied().collect();
let lt_chunk: Vec<&Form8949Row> = lt.iter().skip(k * cap).take(cap).copied().collect();
let short = fill8949::part_data(&st_chunk)?;
let long = fill8949::part_data(<_chunk)?;
copies.push(fill8949::fill_8949_parts(&short, &long, &map)?);
}
overflow::merge_copies(&copies)
}
fn div_ceil(n: usize, d: usize) -> usize {
n.div_ceil(d)
}
pub fn stamp_draft_watermark(pdf_bytes: &[u8]) -> Result<Vec<u8>, FormsError> {
watermark::stamp_draft(pdf_bytes)
}
pub fn fill_schedule_d(totals: &ScheduleDTotals, year: i32) -> Result<Vec<u8>, FormsError> {
let map = ScheduleDMap::for_year(year)?;
schedule_d::fill_schedule_d_totals(totals, &map)
}
pub fn fill_schedule_se(
se: &btctax_core::SeTaxResult,
w2_ss_wages: Usd,
ss_wage_base: Usd,
year: i32,
) -> Result<Option<Vec<u8>>, FormsError> {
let map = ScheduleSeMap::for_year(year)?;
schedule_se::fill_schedule_se_with_map(se, w2_ss_wages, ss_wage_base, &map)
}
pub fn fill_form_8959(
lines: &btctax_core::tax::other_taxes::Form8959Lines,
header: &btctax_core::tax::packet::ReturnHeader,
year: i32,
) -> Result<Option<Vec<u8>>, FormsError> {
let map = Form8959Map::for_year(year)?;
form8959::fill_form_8959_with_map(lines, header, &map)
}
pub fn fill_form_8960(
lines: &btctax_core::tax::other_taxes::Form8960Lines,
header: &btctax_core::tax::packet::ReturnHeader,
year: i32,
) -> Result<Vec<u8>, FormsError> {
let map = Form8960Map::for_year(year)?;
form8960::fill_form_8960_with_map(lines, header, &map)
}
pub fn fill_form_8995(
lines: &btctax_core::tax::qbi::Form8995Lines,
header: &btctax_core::tax::packet::ReturnHeader,
year: i32,
) -> Result<Vec<u8>, FormsError> {
let map = Form8995Map::for_year(year)?;
form8995::fill_form_8995_with_map(lines, header, &map)
}
pub fn fill_schedule_1(
lines: &btctax_core::tax::printed::Schedule1Lines,
header: &btctax_core::tax::packet::ReturnHeader,
year: i32,
) -> Result<Vec<u8>, FormsError> {
let map = Schedule1Map::for_year(year)?;
schedule23::fill_schedule_1_with_map(lines, header, &map)
}
pub fn fill_schedule_2(
lines: &btctax_core::tax::printed::Schedule2Lines,
header: &btctax_core::tax::packet::ReturnHeader,
year: i32,
) -> Result<Vec<u8>, FormsError> {
let map = Schedule2Map::for_year(year)?;
schedule23::fill_schedule_2_with_map(lines, header, &map)
}
pub fn fill_schedule_3(
lines: &btctax_core::tax::printed::Schedule3Lines,
header: &btctax_core::tax::packet::ReturnHeader,
year: i32,
) -> Result<Vec<u8>, FormsError> {
let map = Schedule3Map::for_year(year)?;
schedule23::fill_schedule_3_with_map(lines, header, &map)
}
pub fn fill_schedule_a(
lines: &btctax_core::tax::printed::ScheduleALines,
header: &btctax_core::tax::packet::ReturnHeader,
year: i32,
) -> Result<Vec<u8>, FormsError> {
let map = ScheduleAMap::for_year(year)?;
schedule_a::fill_schedule_a_with_map(lines, header, &map)
}
pub fn fill_form_1040_full(
lines: &btctax_core::tax::printed::Form1040Lines,
header: &btctax_core::tax::packet::ReturnHeader,
status: btctax_core::tax::types::FilingStatus,
year: i32,
) -> Result<Vec<u8>, FormsError> {
let map = Form1040Map::for_year(year)?;
form1040_full::fill_form_1040_full_with_map(lines, header, status, &map)
}
pub fn fill_schedule_d_full(
lines: &btctax_core::tax::printed::ScheduleDLines,
header: &btctax_core::tax::packet::ReturnHeader,
year: i32,
) -> Result<Vec<u8>, FormsError> {
let map = ScheduleDMap::for_year(year)?;
schedule_d_full::fill_schedule_d_full_with_map(lines, header, &map)
}
pub fn fill_form_8275(
printed: &btctax_core::tax::printed::Printed8275,
header: &btctax_core::tax::packet::ReturnHeader,
year: i32,
) -> Result<Option<Vec<u8>>, FormsError> {
form8275::fill_form_8275(printed, header, year)
}
pub fn fill_form_8275_slice(
printed: &btctax_core::tax::printed::Printed8275,
year: i32,
) -> Result<Option<Vec<u8>>, FormsError> {
form8275::fill_form_8275_slice(printed, year)
}
pub fn part_ii_capacity_check(narrative: &str, year: i32) -> Result<PartIiCapacity, FormsError> {
form8275::part_ii_capacity_check(narrative, year)
}
pub fn fill_form_8283_full(
printed: &btctax_core::tax::printed::Printed8283Rows,
header: &btctax_core::tax::packet::ReturnHeader,
year: i32,
) -> Result<Option<Vec<u8>>, FormsError> {
let map = Form8283Map::for_year(year)?;
form8283::fill_form_8283_full(printed, header, &map)
}
pub fn fill_8949_full(
printed: &btctax_core::tax::printed::Printed8949,
header: &btctax_core::tax::packet::ReturnHeader,
year: i32,
) -> Result<Vec<u8>, FormsError> {
let map = Form8949Map::for_year(year)?;
fill8949_full::fill_8949_full_with_map(printed, header, &map)
}
pub fn fill_schedule_se_full(
lines: &btctax_core::tax::printed::ScheduleSeLines,
header: &btctax_core::tax::packet::ReturnHeader,
year: i32,
) -> Result<Vec<u8>, FormsError> {
let map = ScheduleSeMap::for_year(year)?;
schedule_se_full::fill_schedule_se_full_with_map(lines, header, &map)
}
pub fn fill_schedule_b(
lines: &btctax_core::tax::printed::ScheduleBLines,
header: &btctax_core::tax::packet::ReturnHeader,
year: i32,
) -> Result<Vec<u8>, FormsError> {
let map = ScheduleBMap::for_year(year)?;
schedule_b::fill_schedule_b_with_map(lines, header, &map)
}
pub fn fill_schedule_c(
lines: &btctax_core::tax::printed::ScheduleCLines,
header: &btctax_core::tax::packet::ReturnHeader,
year: i32,
) -> Result<Vec<u8>, FormsError> {
let map = ScheduleCMap::for_year(year)?;
schedule_c::fill_schedule_c_with_map(lines, header, &map)
}
pub fn fill_form_8283(
rows: &[btctax_core::Form8283Row],
year: i32,
) -> Result<Option<Vec<u8>>, FormsError> {
let map = Form8283Map::for_year(year)?;
form8283::fill_form_8283(rows, &map)
}
pub fn fill_form_1040_capgains(
inputs: &Form1040Inputs,
year: i32,
) -> Result<Option<Form1040Fill>, FormsError> {
let map = Form1040Map::for_year(year)?;
form1040::fill_form_1040_capgains(inputs, &map)
}
pub fn rows_possibly_broker_reported(rows: &[Form8949Row]) -> usize {
rows.iter().filter(|r| r.box_needs_review).count()
}
#[doc(hidden)]
pub use packet::{fill_full_return, NamedForm};
pub mod testonly {
pub use crate::cells::fmt_money_pair;
pub use crate::fill8949::{fill_8949_parts, part_data, pdf_has_xfa, split_parts, PartData};
pub use crate::fill8949_full::fill_8949_full_with_map;
pub use crate::form1040::{fill_form_1040_capgains as fill_1040_with_map, Form1040Fill};
pub use crate::form1040_full::fill_form_1040_full_with_map;
pub use crate::form8275::fill_form_8275_with_map as fill_8275_with_map;
pub use crate::form8283::fill_form_8283 as fill_8283_with_map;
pub use crate::form8959::fill_form_8959_with_map;
pub use crate::form8960::fill_form_8960_with_map;
pub use crate::form8995::fill_form_8995_with_map;
pub use crate::map::{
AmountCols, Form1040Map, Form8275Map, Form8275Row, Form8283Map, Form8949Map, Form8959Map,
Form8960Map, Form8995Map, MoneyCell, MoneyPair, PartMap, Schedule1Map, Schedule2Map,
Schedule3Map, ScheduleAMap, ScheduleBMap, ScheduleCMap, ScheduleDMap, ScheduleSeMap,
};
pub use crate::map::{
F1040_MAP_2024, F8275_MAP_2024, F8283_MAP_2024, F8949_MAP_2024, F8959_MAP_2024,
F8960_MAP_2024, F8995_MAP_2024, SCHEDULE_1_MAP_2024, SCHEDULE_2_MAP_2024,
SCHEDULE_3_MAP_2024, SCHEDULE_A_MAP_2024, SCHEDULE_B_MAP_2024, SCHEDULE_C_MAP_2024,
SCHEDULE_D_MAP_2024, SCHEDULE_SE_MAP_2024,
};
pub use crate::pdf::{
button_on_states, checkbox_on, collect_fields, index, load, text_value, Field,
F1040_PDF_2017, F1040_PDF_2024, F1040_PDF_2025, F8275_PDF_2024, F8283_PDF_2017,
F8283_PDF_2024, F8283_PDF_2025, F8949_PDF_2017, F8949_PDF_2024, F8949_PDF_2025,
F8959_PDF_2024, SCHEDULE_D_PDF_2017, SCHEDULE_D_PDF_2024, SCHEDULE_D_PDF_2025,
SCHEDULE_SE_PDF_2017, SCHEDULE_SE_PDF_2024, SCHEDULE_SE_PDF_2025,
};
pub use crate::schedule23::{
fill_schedule_1_with_map, fill_schedule_2_with_map, fill_schedule_3_with_map,
};
pub use crate::schedule_a::fill_schedule_a_with_map;
pub use crate::schedule_b::fill_schedule_b_with_map;
pub use crate::schedule_c::fill_schedule_c_with_map;
pub use crate::schedule_d::fill_schedule_d_totals;
pub use crate::schedule_d_full::fill_schedule_d_full_with_map;
pub use crate::schedule_se::fill_schedule_se_with_map;
pub use crate::schedule_se_full::fill_schedule_se_full_with_map;
pub use crate::transcribe::extract_lines;
pub use crate::verify::{
no_unmapped_filled, topmost_yes_no_pair, verify_8949, verify_flat, FlatPlacement, Geo,
Placement,
};
}