title: Return a generic struct which the generic type is NOT known in advance by the caller
body: <p>Let me retell my problem with the real use case i am doing:</p>
  <pre class="lang-rust prettyprint-override"><code>use tensorflow::{
      DataType, Graph, Operation, SavedModelBundle, SessionOptions, Tensor
  };
  
  #[derive(Debug)]
  struct SigMD {
      op: Operation,
      index: i32,
      dtype: DataType,
      shape: Option&lt;Vec&lt;Option&lt;i64&gt;&gt;&gt;,
      dims: Option&lt;usize&gt;,
  }
  
  #[derive(Debug)]
  struct Sig {
      method_name: String,
      inputs: HashMap&lt;String, SigMD&gt;,
      outputs: HashMap&lt;String, SigMD&gt;,
  }
  
  pub struct TFModel {
      bundle: SavedModelBundle,
      sigs: HashMap&lt;String, Sig&gt;,
  }
  
  impl TFModel {
      pub fn load&lt;P: AsRef&lt;Path&gt;&gt;(
          saved_model_dir: P, tags: Option&lt;&amp;[&amp;str]&gt;, options: Option&lt;&amp;SessionOptions&gt;,
      ) -&gt; anyhow::Result&lt;Self&gt; {
  
          // Eventually return the loaded model instance if everything is ok.
          Ok(Self { bundle, sigs })
      }
  }
  
  pub trait Predictor {
      fn predict&lt;Sig: AsRef&lt;str&gt;, K: AsRef&lt;str&gt;, V: AsRef&lt;[u8]&gt;&gt;(
          &amp;self, sig: Sig, inputs: &amp;HashMap&lt;K, V&gt;,
      ) -&gt; anyhow::Result&lt;HashMap&lt;K, Tensor&lt;T&gt;&gt;&gt;;
  }
  
  impl Predictor for TFModel {
      fn predict&lt;Sig: AsRef&lt;str&gt;, K: AsRef&lt;str&gt;, V: AsRef&lt;[u8]&gt;&gt;(
          &amp;self, sig: Sig, inputs: &amp;HashMap&lt;K, V&gt;,
      ) -&gt; anyhow::Result&lt;HashMap&lt;K, Tensor&lt;T&gt;&gt;&gt;;
  }
  </code></pre>
  <p>As you can see above i am trying to design a generic <code>trait Predictor</code> for various TensorFlow models.</p>
  <p>After the model was loaded, the <code>&amp;self</code> contains different <code>inputs</code> and <code>outputs</code> tensor infos for different signatures, then the <code>trait Predictor.predict</code> function takes the <code>&amp;self, sig: AsRef&lt;str&gt;, inputs: &amp;HashMap&lt;AsRef&lt;str&gt;, AsRef&lt;[u8]&gt;&gt;</code>, and tries to the below:</p>
  <ol>
  <li>Use the <code>sig</code> to query the input tensor infos from the <code>&amp;self</code>, and then convert the corresponding <code>AsRef&lt;[u8]&gt;</code> accordingly, like <code>u8 -&gt; u16/f32</code>, then <code>reshape</code> etc;</li>
  <li>Use the converted inputs to call <a href="https://tensorflow.github.io/rust/tensorflow/struct.SessionRunArgs.html#method.add_feed" rel="nofollow noreferrer">add_feed</a>, and then eventually <a href="https://tensorflow.github.io/rust/tensorflow/struct.SessionRunArgs.html#method.fetch" rel="nofollow noreferrer">fetch outputs</a>;</li>
  <li>Finally return an instance of <a href="https://tensorflow.github.io/rust/tensorflow/struct.Tensor.html" rel="nofollow noreferrer">tensorflow::Tensor</a> if everything is ok;</li>
  </ol>
  <p>I am able to get all of these work for different types of <strong>individual</strong> models, but i am using the concrete rust types after seeing the model <code>inputs/outputs</code> tensor infos for the model, such as:</p>
  <p>inputs:</p>
  <pre class="lang-json prettyprint-override"><code>{
      &quot;input_tensor&quot;:&quot;TensorInfo&quot;{
          &quot;op&quot;:&quot;Operation&quot;{
              &quot;inner&quot;:0x7fe0e80ab048,
              &quot;gimpl&quot;:&quot;GraphImpl&quot;{
                  &quot;inner&quot;:0x7fe0e800ca00,
                  &quot;owned&quot;:true
              }
          },
          &quot;index&quot;:0,
          &quot;dtype&quot;:UInt8,
          &quot;shape&quot;:&quot;Some(&quot;[
              Some(1),
              &quot;None&quot;,
              &quot;None&quot;,
              Some(3)
          ]&quot;)&quot;,
          &quot;dims&quot;:Some(4)
      }
  }
  </code></pre>
  <p>outputs:</p>
  <pre class="lang-json prettyprint-override"><code>{
      &quot;detection_anchor_indices&quot;:&quot;TensorInfo&quot;{
          &quot;op&quot;:&quot;Operation&quot;{
              &quot;inner&quot;:0x7fe0e80ab110,
              &quot;gimpl&quot;:&quot;GraphImpl&quot;{
                  &quot;inner&quot;:0x7fe0e800ca00,
                  &quot;owned&quot;:true
              }
          },
          &quot;index&quot;:0,
          &quot;dtype&quot;:&quot;Float&quot;,
          &quot;shape&quot;:&quot;Some(&quot;[
              Some(1),
              Some(100)
          ]&quot;)&quot;,
          &quot;dims&quot;:Some(2)
      },
      &quot;num_detections&quot;:&quot;TensorInfo&quot;{
          &quot;op&quot;:&quot;Operation&quot;{
              &quot;inner&quot;:0x7fe0e80ab110,
              &quot;gimpl&quot;:&quot;GraphImpl&quot;{
                  &quot;inner&quot;:0x7fe0e800ca00,
                  &quot;owned&quot;:true
              }
          },
          &quot;index&quot;:5,
          &quot;dtype&quot;:&quot;Float&quot;,
          &quot;shape&quot;:&quot;Some(&quot;[
              Some(1)
          ]&quot;)&quot;,
          &quot;dims&quot;:Some(1)
      },
      &quot;detection_classes&quot;:&quot;TensorInfo&quot;{
          &quot;op&quot;:&quot;Operation&quot;{
              &quot;inner&quot;:0x7fe0e80ab110,
              &quot;gimpl&quot;:&quot;GraphImpl&quot;{
                  &quot;inner&quot;:0x7fe0e800ca00,
                  &quot;owned&quot;:true
              }
          },
          &quot;index&quot;:2,
          &quot;dtype&quot;:&quot;Float&quot;,
          &quot;shape&quot;:&quot;Some(&quot;[
              Some(1),
              Some(100)
          ]&quot;)&quot;,
          &quot;dims&quot;:Some(2)
      },
      &quot;raw_detection_boxes&quot;:&quot;TensorInfo&quot;{
          &quot;op&quot;:&quot;Operation&quot;{
              &quot;inner&quot;:0x7fe0e80ab110,
              &quot;gimpl&quot;:&quot;GraphImpl&quot;{
                  &quot;inner&quot;:0x7fe0e800ca00,
                  &quot;owned&quot;:true
              }
          },
          &quot;index&quot;:6,
          &quot;dtype&quot;:&quot;Float&quot;,
          &quot;shape&quot;:&quot;Some(&quot;[
              Some(1),
              Some(1917),
              Some(4)
          ]&quot;)&quot;,
          &quot;dims&quot;:Some(3)
      },
      &quot;detection_boxes&quot;:&quot;TensorInfo&quot;{
          &quot;op&quot;:&quot;Operation&quot;{
              &quot;inner&quot;:0x7fe0e80ab110,
              &quot;gimpl&quot;:&quot;GraphImpl&quot;{
                  &quot;inner&quot;:0x7fe0e800ca00,
                  &quot;owned&quot;:true
              }
          },
          &quot;index&quot;:1,
          &quot;dtype&quot;:&quot;Float&quot;,
          &quot;shape&quot;:&quot;Some(&quot;[
              Some(1),
              Some(100),
              Some(4)
          ]&quot;)&quot;,
          &quot;dims&quot;:Some(3)
      },
      &quot;detection_scores&quot;:&quot;TensorInfo&quot;{
          &quot;op&quot;:&quot;Operation&quot;{
              &quot;inner&quot;:0x7fe0e80ab110,
              &quot;gimpl&quot;:&quot;GraphImpl&quot;{
                  &quot;inner&quot;:0x7fe0e800ca00,
                  &quot;owned&quot;:true
              }
          },
          &quot;index&quot;:4,
          &quot;dtype&quot;:&quot;Float&quot;,
          &quot;shape&quot;:&quot;Some(&quot;[
              Some(1),
              Some(100)
          ]&quot;)&quot;,
          &quot;dims&quot;:Some(2)
      },
      &quot;raw_detection_scores&quot;:&quot;TensorInfo&quot;{
          &quot;op&quot;:&quot;Operation&quot;{
              &quot;inner&quot;:0x7fe0e80ab110,
              &quot;gimpl&quot;:&quot;GraphImpl&quot;{
                  &quot;inner&quot;:0x7fe0e800ca00,
                  &quot;owned&quot;:true
              }
          },
          &quot;index&quot;:7,
          &quot;dtype&quot;:&quot;Float&quot;,
          &quot;shape&quot;:&quot;Some(&quot;[
              Some(1),
              Some(1917),
              Some(91)
          ]&quot;)&quot;,
          &quot;dims&quot;:Some(3)
      },
      &quot;detection_multiclass_scores&quot;:&quot;TensorInfo&quot;{
          &quot;op&quot;:&quot;Operation&quot;{
              &quot;inner&quot;:0x7fe0e80ab110,
              &quot;gimpl&quot;:&quot;GraphImpl&quot;{
                  &quot;inner&quot;:0x7fe0e800ca00,
                  &quot;owned&quot;:true
              }
          },
          &quot;index&quot;:3,
          &quot;dtype&quot;:&quot;Float&quot;,
          &quot;shape&quot;:&quot;Some(&quot;[
              Some(1),
              Some(100),
              Some(91)
          ]&quot;)&quot;,
          &quot;dims&quot;:Some(3)
      }
  }
  </code></pre>
  <p>Then i can do something like this:</p>
  <pre class="lang-rust prettyprint-override"><code>let img = image::open(
      constants::LOCAL_EXT_RESOURCES_DIR_PATH.as_path().join(&quot;payloads/kirito_n_asuna.png&quot;),
  )
  .unwrap();
  
  let (w, h) = img.dimensions();
  
  const NORM_SCALE: f32 = 1. / 255.;
  
  let input_tensor =
      Tensor::new(&amp;[1, w.into(), h.into(), 3]).with_values(&amp;img.to_bytes()).unwrap();
  
  // Or i need to convert it to Vec&lt;f32&gt;
  // const NORM_SCALE: f32 = 1. / 255.;
  // let im = image::load_from_memory(&amp;bytes)?
  //  .resize_exact(28, 28, FilterType::Nearest)
  //  .grayscale()
  //  .to_bytes()
  //  .into_iter()
  //  .map(|x| (x as f32) * NORM_SCALE)
  //  .collect::&lt;Vec&lt;f32&gt;&gt;();
  
  let mut run_args = SessionRunArgs::new();
  let sig = &amp;model.sigs[&quot;serving_default&quot;];
  println!(&quot;{:?}&lt;&lt;=============&gt;&gt;{:?}&quot;, sig.inputs, sig.outputs);
  run_args.add_feed(
      &amp;sig.inputs[&quot;input_tensor&quot;].op,
      sig.inputs[&quot;input_tensor&quot;].index,
      &amp;input_tensor,
  );
  
  let num_detections_fetch = run_args
      .request_fetch(&amp;sig.outputs[&quot;num_detections&quot;].op, sig.outputs[&quot;num_detections&quot;].index);
  
  let detection_scores_fetch = run_args
      .request_fetch(&amp;sig.outputs[&quot;detection_scores&quot;].op, sig.outputs[&quot;detection_scores&quot;].index);
  
  model.bundle.session.run(&amp;mut run_args).unwrap();
  
  let num_detections = run_args.fetch::&lt;f32&gt;(num_detections_fetch).unwrap();
  let detection_scores = run_args.fetch::&lt;f32&gt;(detection_scores_fetch).unwrap();
  </code></pre>
  <p>As you can see from the above code snippet i am using some concrete rust types to create the <code>tensorflow::Tensor&lt;T&gt;</code>, like <code>::&lt;f32&gt;</code> in the <code>let num_detections = run_args.fetch::&lt;f32&gt;(num_detections_fetch).unwrap();</code>, because after seeing the model signature i know it says for this key <code>num_detections</code> it is <code>&quot;dtype&quot;:&quot;Float&quot;,</code>.</p>
  <p><strong>But for different models, different signature and different inputs keys, the return type could be any of these <a href="https://tensorflow.github.io/rust/tensorflow/enum.DataType.html" rel="nofollow noreferrer">DataTpe</a>, and the return is independent from the inputs, also the caller wouldn't know in advance what actual type it will get eventually.</strong></p>
  <p><strong>With these context, how can make the <code>trait Predictor.predict</code> function's return types be generic?</strong></p>