frpc_lib/loader/
reflection_checker.rs1use std::error::Error;
2
3use anyhow::Result;
4
5use super::{reflection_loader_v1, reflection_loader_v1alpha};
6
7#[derive(Debug)]
8pub enum TryGetReflectionVersionResponse {
9 DetectedVersion(ReflectionVersion),
10 VersionUndetectable,
11 ConnectionError { error: Box<dyn Error + Send + Sync> },
12}
13
14#[derive(Debug)]
15pub enum ReflectionVersion {
16 V1,
17 V1Alpha,
18}
19
20pub(crate) async fn try_get_reflection_version(
21 server_url: String,
22) -> Result<TryGetReflectionVersionResponse> {
23 let v1_implemented = reflection_loader_v1::check_implemented(server_url.clone()).await;
24
25 match v1_implemented {
26 Ok(true) => {
27 return Ok(TryGetReflectionVersionResponse::DetectedVersion(
28 ReflectionVersion::V1,
29 ))
30 }
31 Ok(_) => {}
32 Err(e) => {
33 if let Some(transport) = &e.downcast_ref::<tonic::transport::Error>() {
34 let source = transport.source();
35
36 match source {
37 Some(source) => {
38 if source.is::<tonic::ConnectError>() {
39 return Ok(TryGetReflectionVersionResponse::ConnectionError {
40 error: e.into(),
41 });
42 }
43 }
44 None => {}
45 };
46 }
47 }
48 };
49
50 let v1alpha_implemented = reflection_loader_v1alpha::check_implemented(server_url).await;
51
52 match v1alpha_implemented {
53 Ok(true) => {
54 return Ok(TryGetReflectionVersionResponse::DetectedVersion(
55 ReflectionVersion::V1Alpha,
56 ))
57 }
58 Ok(_) => {}
59 Err(e) => {
60 if let Some(transport) = &e.downcast_ref::<tonic::transport::Error>() {
61 let source = transport.source();
62
63 match source {
64 Some(source) => {
65 if source.is::<tonic::ConnectError>() {
66 return Ok(TryGetReflectionVersionResponse::ConnectionError {
67 error: e.into(),
68 });
69 }
70 }
71 None => {}
72 };
73 }
74 }
75 };
76
77 Ok(TryGetReflectionVersionResponse::VersionUndetectable)
78}