diff options
author | Kyle Kelley <rgbkrk@gmail.com> | 2023-09-17 09:38:52 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-17 10:38:52 -0600 |
commit | 81d6ea8e1174d2b74c2a4806eaf279115cb3068f (patch) | |
tree | db527e4888be7102dd20c0b3c68663ff0cddc575 /cli/tools/jupyter/server.rs | |
parent | 23bf05cff265c11927b853003dab6c74b4712ec8 (diff) |
feat(jupyter-kernel): accept nested objects from display calls (#20537)
Closes #20535.
# Screenshots
## JSON
<img width="779" alt="image"
src="https://github.com/denoland/deno/assets/836375/668bb1a6-3f76-4b36-974e-cdc6c93f94c3">
## Vegalite
<img width="558" alt="image"
src="https://github.com/denoland/deno/assets/836375/a5e70908-6b87-42d8-85c3-1323ad52a00f">
# Implementation
Instead of going the route of recursively getting all the objects under
`application/.*json` keys, I went with `JSON.stringify`ing in denospace
then parsing it from rust. One of the key benefits of serializing and
deserializing is that non-JSON-able entries will get stripped
automatically. This also keeps the code pretty simple.
In the future we should _only_ do this for `application/.*json` keys.
cc @mmastrac
Diffstat (limited to 'cli/tools/jupyter/server.rs')
-rw-r--r-- | cli/tools/jupyter/server.rs | 53 |
1 files changed, 15 insertions, 38 deletions
diff --git a/cli/tools/jupyter/server.rs b/cli/tools/jupyter/server.rs index e3e712065..2ed1a61d8 100644 --- a/cli/tools/jupyter/server.rs +++ b/cli/tools/jupyter/server.rs @@ -480,57 +480,34 @@ async fn get_jupyter_display( session: &mut repl::ReplSession, evaluate_result: &cdp::RemoteObject, ) -> Result<Option<HashMap<String, serde_json::Value>>, AnyError> { - let mut data = HashMap::default(); let response = session .call_function_on_args( r#"function (object) {{ - return object[Symbol.for("Jupyter.display")](); - }}"# + return JSON.stringify(object[Symbol.for("Jupyter.display")]()); + }}"# .to_string(), &[evaluate_result.clone()], ) .await?; - if response.exception_details.is_some() { + if let Some(exception_details) = &response.exception_details { + // TODO(rgbkrk): Return an error in userspace instead of Jupyter logs + eprintln!("Exception encountered: {}", exception_details.text); return Ok(None); } - let object_id = response.result.object_id.unwrap(); - - let get_properties_response_result = session - .post_message_with_event_loop( - "Runtime.getProperties", - Some(cdp::GetPropertiesArgs { - object_id, - own_properties: Some(true), - accessor_properties_only: None, - generate_preview: None, - non_indexed_properties_only: Some(true), - }), - ) - .await; - - let Ok(get_properties_response) = get_properties_response_result else { - return Ok(None); - }; + if let Some(serde_json::Value::String(json_str)) = response.result.value { + let data: HashMap<String, serde_json::Value> = + serde_json::from_str(&json_str)?; - let get_properties_response: cdp::GetPropertiesResponse = - serde_json::from_value(get_properties_response).unwrap(); - - for prop in get_properties_response.result.into_iter() { - if let Some(value) = &prop.value { - data.insert( - prop.name.to_string(), - value - .value - .clone() - .unwrap_or_else(|| serde_json::Value::Null), - ); + if !data.is_empty() { + return Ok(Some(data)); } - } - - if !data.is_empty() { - return Ok(Some(data)); + } else { + eprintln!( + "Unexpected response from Jupyter.display: {:?}", + response.result.clone().value + ); } Ok(None) |