Repository: GraphiteEditor/Graphite
File: editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/node_properties.rs (Rust)

Code before:
			.trim()
			.split("),")
			.filter(|x| !x.is_empty())
			.map(|item| {
				let parts: Vec<_> = item.trim().split(",").filter(|x| !x.is_empty()).collect();
				if parts.len() == 2 {
					let x = parts[0].trim().trim_end_matches(')').trim_start_matches('(').trim().parse::<f64>().ok()?;
					let y = parts[1].trim().trim_end_matches(')').trim_start_matches('(').trim().parse::<f64>().ok()?;
					Some(DVec2 { x: x, y: y })
				} else {
					None
				}
			})
			.collect::<Option<Vec<_>>>()
			.map(TaggedValue::VecDVec2)
	};

	if let NodeInput::Value {
		tagged_value: TaggedValue::VecDVec2(x),
		exposed: false,
	} = &document_node.inputs[index]
	{
		widgets.extend_from_slice(&[
			Separator::new(SeparatorType::Unrelated).widget_holder(),
			text_props
				.value(x.iter().map(|v| v.to_string()).collect::<Vec<_>>().join(", ").replace("]", ")").replace("[", "("))
				.on_update(optionally_update_value(move |x: &TextInput| from_string(&x.value), node_id, index))
				.widget_holder(),
		])
	}
	widgets
}

fn font_inputs(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> (Vec<WidgetHolder>, Option<Vec<WidgetHolder>>) {
	let mut first_widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
	let mut second_widgets = None;

	let from_font_input = |font: &FontInput| TaggedValue::Font(Font::new(font.font_family.clone(), font.font_style.clone()));

	if let NodeInput::Value {
		tagged_value: TaggedValue::Font(font),
		exposed: false,
	} = &document_node.inputs[index]
	{
		first_widgets.extend_from_slice(&[
			Separator::new(SeparatorType::Unrelated).widget_holder(),
			FontInput::new(font.font_family.clone(), font.font_style.clone())
				.on_update(update_value(from_font_input, node_id, index))
				.widget_holder(),
		]);
		second_widgets = Some(vec![

Review comment (suggestion):
Could be shortened to:
```rs
.value(x.iter().map(|v| format!("({}, {})", v.x, v.y)).collect::<Vec<_>>().join(", ")
```

Code after:
			.map(TaggedValue::VecDVec2)
	};

	if let NodeInput::Value {
		tagged_value: TaggedValue::VecDVec2(x),
		exposed: false,
	} = &document_node.inputs[index]
	{
		widgets.extend_from_slice(&[
			Separator::new(SeparatorType::Unrelated).widget_holder(),
			text_props
				.value(x.iter().map(|v| format!("({}, {})", v.x, v.y)).collect::<Vec<_>>().join(", "))
				.on_update(optionally_update_value(move |x: &TextInput| from_string(&x.value), node_id, index))
				.widget_holder(),
		])
	}
	widgets
}

fn font_inputs(document_node: &DocumentNode, node_id: NodeId, index: usize, name: &str, blank_assist: bool) -> (Vec<WidgetHolder>, Option<Vec<WidgetHolder>>) {
	let mut first_widgets = start_widgets(document_node, node_id, index, name, FrontendGraphDataType::General, blank_assist);
	let mut second_widgets = None;

	let from_font_input = |font: &FontInput| TaggedValue::Font(Font::new(font.font_family.clone(), font.font_style.clone()));

	if let NodeInput::Value {
		tagged_value: TaggedValue::Font(font),
		exposed: false,
	} = &document_node.inputs[index]
	{
		first_widgets.extend_from_slice(&[
			Separator::new(SeparatorType::Unrelated).widget_holder(),
			FontInput::new(font.font_family.clone(), font.font_style.clone())
				.on_update(update_value(from_font_input, node_id, index))
				.widget_holder(),
		]);
		second_widgets = Some(vec![
			TextLabel::new("").widget_holder(),
			Separator::new(SeparatorType::Unrelated).widget_holder(),
			Separator::new(SeparatorType::Unrelated).widget_holder(),
			Separator::new(SeparatorType::Unrelated).widget_holder(),
			Separator::new(SeparatorType::Unrelated).widget_holder(),
			Separator::new(SeparatorType::Unrelated).widget_holder(),
			FontInput::new(font.font_family.clone(), font.font_style.clone())
				.is_style_picker(true)
				.on_update(update_value(from_font_input, node_id, index))
				.widget_holder(),
		]);
	}
	(first_widgets, second_widgets)
}