use super::doc::*;
use super::*;
trait ToConstantValue {
fn get_constant_value(&self) -> String;
}
trait PossiblyVoidReturnValue {
fn get_optional_constant_value(&self) -> Option<String>;
}
impl<T> PossiblyVoidReturnValue for T
where
T: ToConstantValue,
{
fn get_optional_constant_value(&self) -> Option<String> {
Some(self.get_constant_value())
}
}
impl ToConstantValue for PrimitiveValue {
fn get_constant_value(&self) -> String {
match self {
PrimitiveValue::Bool(x) => x.to_string(),
PrimitiveValue::U8(x) => format!("UByte.valueOf({x})"),
PrimitiveValue::S8(x) => x.to_string(),
PrimitiveValue::U16(x) => format!("UShort.valueOf({x})"),
PrimitiveValue::S16(x) => x.to_string(),
PrimitiveValue::U32(x) => format!("UInteger.valueOf({x})"),
PrimitiveValue::S32(x) => x.to_string(),
PrimitiveValue::U64(x) => format!("ULong.valueOf({x})"),
PrimitiveValue::S64(x) => x.to_string(),
PrimitiveValue::Float(x) => x.to_string(),
PrimitiveValue::Double(x) => x.to_string(),
}
}
}
impl ToConstantValue for DurationValue {
fn get_constant_value(&self) -> String {
match self {
DurationValue::Milliseconds(x) => format!("java.time.Duration.ofMillis({x})"),
DurationValue::Seconds(x) => format!("java.time.Duration.ofSeconds({x})"),
}
}
}
impl ToConstantValue for BasicValue {
fn get_constant_value(&self) -> String {
match self {
BasicValue::Primitive(x) => x.get_constant_value(),
BasicValue::Duration(x) => x.get_constant_value(),
BasicValue::Enum(x) => {
format!(
"{}.{}",
x.handle.name.camel_case(),
x.variant.name.capital_snake_case()
)
}
}
}
}
impl ToConstantValue for ZeroParameterStructInitializer {
fn get_constant_value(&self) -> String {
match self.initializer.initializer_type {
InitializerType::Normal => format!("new {}()", self.handle.name().camel_case()),
InitializerType::Static => format!(
"{}.{}()",
self.handle.name().camel_case(),
self.initializer.name.mixed_case()
),
}
}
}
impl PossiblyVoidReturnValue for DefaultCallbackReturnValue {
fn get_optional_constant_value(&self) -> Option<String> {
match self {
DefaultCallbackReturnValue::Void => None,
DefaultCallbackReturnValue::Basic(x) => x.get_optional_constant_value(),
DefaultCallbackReturnValue::InitializedStruct(x) => x.get_optional_constant_value(),
}
}
}
pub(crate) fn generate(
f: &mut dyn Printer,
interface: &Handle<Interface<Validated>>,
) -> FormattingResult<()> {
let interface_name = interface.name.camel_case();
documentation(f, |f| {
javadoc_print(f, &interface.doc)
})?;
if interface.is_functional() {
f.writeln("@FunctionalInterface")?;
}
f.writeln(&format!("public interface {interface_name}"))?;
blocked(f, |f| {
for func in interface.callbacks.iter() {
let constant_return_value = func
.default_implementation
.as_ref()
.map(|x| x.get_optional_constant_value());
documentation(f, |f| {
javadoc_print(f, &func.doc)?;
f.newline()?;
if let Some(v) = &constant_return_value {
match v {
None => {
f.writeln(
"<p>The default implementation of this method does nothing</p>",
)?;
}
Some(value) => {
f.writeln(&format!(
"<p>The default implementation of this method returns '{value}'</p>"
))?;
}
}
f.newline()?;
}
for arg in &func.arguments {
f.writeln(&format!("@param {} ", arg.name.mixed_case()))?;
docstring_print(f, &arg.doc)?;
}
if let Some(doc) = &func.return_type.get_doc() {
f.writeln("@return ")?;
docstring_print(f, doc)?;
}
Ok(())
})?;
let modifier = if func.default_implementation.is_some() {
"default "
} else {
""
};
f.writeln(&format!(
"{}{} {}(",
modifier,
func.return_type.as_java_primitive(),
func.name.mixed_case()
))?;
f.write(
&func
.arguments
.iter()
.map(|arg| {
format!(
"{} {}",
arg.arg_type.as_java_primitive(),
arg.name.mixed_case()
)
})
.collect::<Vec<String>>()
.join(", "),
)?;
match constant_return_value {
None => f.write(");")?,
Some(None) => f.write(") {}")?,
Some(Some(v)) => {
f.write(")")?;
blocked(f, |f| f.writeln(&format!("return {v};")))?;
}
}
f.newline()?;
}
Ok(())
})
}