| 1723 |
1723 |
|
/// open. R9 holds here as everywhere else -- the field is built whether or not
|
| 1724 |
1724 |
|
/// it is asked -- so a supplier feeding a question nobody sees is still called
|
| 1725 |
1725 |
|
/// and still answers.
|
| 1726 |
|
- |
fn form(action: &Action, body: &[Item]) -> Result<TokenStream> {
|
| 1727 |
|
- |
let mut submit = None;
|
| 1728 |
|
- |
let mut asked = Vec::new();
|
| 1729 |
|
- |
let held = format_ident!("asked", span = Span::call_site());
|
|
1726 |
+ |
/// The statements one form body contributes, and the button it names.
|
|
1727 |
+ |
///
|
|
1728 |
+ |
/// Recursive because a marked run holds fields of its own: a guarded
|
|
1729 |
+ |
/// disclosure puts six questions on the form or none, and they accrete into
|
|
1730 |
+ |
/// the same wrapper the ungated ones do.
|
|
1731 |
+ |
fn form_fields(
|
|
1732 |
+ |
body: &[Item],
|
|
1733 |
+ |
held: &proc_macro2::Ident,
|
|
1734 |
+ |
asked: &mut Vec<TokenStream>,
|
|
1735 |
+ |
submit: &mut Option<TokenStream>,
|
|
1736 |
+ |
) -> Result<()> {
|
| 1730 |
1737 |
|
for (index, item) in body.iter().enumerate() {
|
| 1731 |
1738 |
|
match item {
|
| 1732 |
|
- |
// A form's fields are a bare `Vec`, so there is no container
|
| 1733 |
|
- |
// carrying marks for them yet. Refused rather than dropped: a
|
| 1734 |
|
- |
// staged form with a guarded field would otherwise compile to a
|
| 1735 |
|
- |
// residual with no branch where the fill program has one, and the
|
| 1736 |
|
- |
// filler would find that out on a request.
|
| 1737 |
|
- |
Item::Marked { .. } => {
|
| 1738 |
|
- |
return Err(syn::Error::new(
|
| 1739 |
|
- |
Span::call_site(),
|
| 1740 |
|
- |
"a form's fields cannot be marked yet, so this shape cannot be \
|
| 1741 |
|
- |
staged; give `Node::Form` its own marks first",
|
| 1742 |
|
- |
));
|
|
1739 |
+ |
// A form's fields accrete into a wrapper for the same reason a
|
|
1740 |
+ |
// panel's members do, and the form absorbs their marks as it takes
|
|
1741 |
+ |
// them. `settings::email`'s advanced block is the site: six server
|
|
1742 |
+ |
// questions that are on the form only while the disclosure is open.
|
|
1743 |
+ |
Item::Marked { site, varies, body } => {
|
|
1744 |
+ |
let mut inner = Vec::new();
|
|
1745 |
+ |
form_fields(body, held, &mut inner, submit)?;
|
|
1746 |
+ |
let varies = self::varies(varies)?;
|
|
1747 |
+ |
let plan = format_ident!("{}", crate::symbolic::PLAN, span = Span::call_site());
|
|
1748 |
+ |
let at = format_ident!("asked_from_{index}", span = Span::call_site());
|
|
1749 |
+ |
let to = format_ident!("asked_to_{index}", span = Span::call_site());
|
|
1750 |
+ |
asked.push(quote!({
|
|
1751 |
+ |
let #at = ::quasi_router::stage::Marking::placed(&#held);
|
|
1752 |
+ |
#(#inner)*
|
|
1753 |
+ |
let #to = ::quasi_router::stage::Marking::placed(&#held);
|
|
1754 |
+ |
::quasi_router::stage::Marking::mark(
|
|
1755 |
+ |
&mut #held,
|
|
1756 |
+ |
::quasi_router::stage::Mark {
|
|
1757 |
+ |
scope: #plan.scope(),
|
|
1758 |
+ |
id: #site,
|
|
1759 |
+ |
varies: #varies,
|
|
1760 |
+ |
from: #at,
|
|
1761 |
+ |
to: #to,
|
|
1762 |
+ |
},
|
|
1763 |
+ |
);
|
|
1764 |
+ |
}));
|
| 1743 |
1765 |
|
}
|
| 1744 |
1766 |
|
Item::Attribute {
|
| 1745 |
1767 |
|
name,
|
| 1757 |
1779 |
|
"a form always has a button: `submit` takes no guard",
|
| 1758 |
1780 |
|
));
|
| 1759 |
1781 |
|
}
|
| 1760 |
|
- |
submit = Some(arg(label)?);
|
|
1782 |
+ |
*submit = Some(arg(label)?);
|
| 1761 |
1783 |
|
}
|
| 1762 |
1784 |
|
Item::Emit(Emission::Field {
|
| 1763 |
1785 |
|
kind,
|
| 1766 |
1788 |
|
body,
|
| 1767 |
1789 |
|
}) => {
|
| 1768 |
1790 |
|
let built = field(kind, name, label, body)?;
|
| 1769 |
|
- |
asked.push(quote!(#held.push(#built);));
|
|
1791 |
+ |
asked.push(quote!(#held.value.push(#built);));
|
| 1770 |
1792 |
|
}
|
| 1771 |
1793 |
|
// A question another shape built, which is the courtesy every other
|
| 1772 |
1794 |
|
// container already extends: a table takes a row, a cell takes a
|
| 1776 |
1798 |
|
// `span` twice in one form and `milliseconds` four times across two.
|
| 1777 |
1799 |
|
Item::Emit(Emission::Include(supplier)) => {
|
| 1778 |
1800 |
|
let supplier = self::hole(supplier)?;
|
| 1779 |
|
- |
asked.push(quote!(#held.push(::std::convert::Into::into(#supplier));));
|
|
1801 |
+ |
asked.push(quote!(#held.value.push(::std::convert::Into::into(#supplier));));
|
| 1780 |
1802 |
|
}
|
| 1781 |
1803 |
|
Item::Emit(Emission::Guarded { guard, inner }) => {
|
| 1782 |
1804 |
|
let Emission::Field {
|
| 1797 |
1819 |
|
asked.push(quote!({
|
| 1798 |
1820 |
|
let #question = #built;
|
| 1799 |
1821 |
|
if #test {
|
| 1800 |
|
- |
#held.push(#question);
|
|
1822 |
+ |
#held.value.push(#question);
|
| 1801 |
1823 |
|
}
|
| 1802 |
1824 |
|
}));
|
| 1803 |
1825 |
|
}
|
| 1825 |
1847 |
|
}
|
| 1826 |
1848 |
|
}
|
| 1827 |
1849 |
|
}
|
|
1850 |
+ |
Ok(())
|
|
1851 |
+ |
}
|
|
1852 |
+ |
|
|
1853 |
+ |
fn form(action: &Action, body: &[Item]) -> Result<TokenStream> {
|
|
1854 |
+ |
let mut submit = None;
|
|
1855 |
+ |
let mut asked = Vec::new();
|
|
1856 |
+ |
let held = format_ident!("asked", span = Span::call_site());
|
|
1857 |
+ |
form_fields(body, &held, &mut asked, &mut submit)?;
|
| 1828 |
1858 |
|
let Some(submit) = submit else {
|
| 1829 |
1859 |
|
return Err(syn::Error::new(
|
| 1830 |
1860 |
|
action.verb.span(),
|
| 1832 |
1862 |
|
));
|
| 1833 |
1863 |
|
};
|
| 1834 |
1864 |
|
let action = self::action(action)?;
|
| 1835 |
|
- |
Ok(quote! {
|
| 1836 |
|
- |
::quasi_router::Node::Form {
|
| 1837 |
|
- |
marks: ::quasi_router::stage::Marks::none(),
|
|
1865 |
+ |
Ok(quote! {{
|
|
1866 |
+ |
let mut #held = ::quasi_router::stage::Staged::plain(::std::vec::Vec::new());
|
|
1867 |
+ |
#(#asked)*
|
|
1868 |
+ |
let mut form = ::quasi_router::Node::Form {
|
| 1838 |
1869 |
|
action: #action,
|
| 1839 |
1870 |
|
submit: ::std::convert::Into::into(#submit),
|
| 1840 |
|
- |
fields: {
|
| 1841 |
|
- |
let mut #held = ::std::vec::Vec::new();
|
| 1842 |
|
- |
#(#asked)*
|
| 1843 |
|
- |
#held
|
| 1844 |
|
- |
},
|
| 1845 |
|
- |
}
|
| 1846 |
|
- |
})
|
|
1871 |
+ |
fields: #held.value,
|
|
1872 |
+ |
marks: ::quasi_router::stage::Marks::none(),
|
|
1873 |
+ |
};
|
|
1874 |
+ |
::quasi_router::stage::Marking::absorb(&mut form, &#held.marks, 0);
|
|
1875 |
+ |
form
|
|
1876 |
+ |
}})
|
| 1847 |
1877 |
|
}
|
| 1848 |
1878 |
|
|
| 1849 |
1879 |
|
/// One field: what it asks for, by name, under a label.
|