mirror of
https://github.com/joshuadavidthomas/django-language-server.git
synced 2025-07-24 04:45:02 +00:00
Get rid of all transport types and settle on Protobuf (#25)
* Get rid of all transport types and settle on Protobuf hope i don't regret this * Update Cargo.toml * Update agent.py
This commit is contained in:
parent
643a47953e
commit
0a6e975ca5
38 changed files with 1484 additions and 685 deletions
|
@ -1,5 +1,5 @@
|
|||
use djls_ipc::{JsonResponse, PythonProcess, TransportError, TransportMessage, TransportResponse};
|
||||
use serde::Deserialize;
|
||||
use djls_ipc::v1::*;
|
||||
use djls_ipc::{ProcessError, PythonProcess};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -20,23 +20,6 @@ impl fmt::Display for App {
|
|||
#[derive(Debug, Default)]
|
||||
pub struct Apps(Vec<App>);
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct InstalledAppsCheck {
|
||||
has_app: bool,
|
||||
}
|
||||
|
||||
impl TryFrom<JsonResponse> for InstalledAppsCheck {
|
||||
type Error = TransportError;
|
||||
|
||||
fn try_from(response: JsonResponse) -> Result<Self, Self::Error> {
|
||||
response
|
||||
.data()
|
||||
.clone()
|
||||
.ok_or_else(|| TransportError::Process("No data in response".to_string()))
|
||||
.and_then(|data| serde_json::from_value(data).map_err(TransportError::Json))
|
||||
}
|
||||
}
|
||||
|
||||
impl Apps {
|
||||
pub fn from_strings(apps: Vec<String>) -> Self {
|
||||
Self(apps.into_iter().map(App).collect())
|
||||
|
@ -54,18 +37,21 @@ impl Apps {
|
|||
self.apps().iter()
|
||||
}
|
||||
|
||||
pub fn check_installed(python: &mut PythonProcess, app: &str) -> Result<bool, TransportError> {
|
||||
let message = TransportMessage::Json("installed_apps_check".to_string());
|
||||
let response = python.send(message, Some(vec![app.to_string()]))?;
|
||||
match response {
|
||||
TransportResponse::Json(json_str) => {
|
||||
let json_response: JsonResponse = serde_json::from_str(&json_str)?;
|
||||
let result = InstalledAppsCheck::try_from(json_response)?;
|
||||
Ok(result.has_app)
|
||||
}
|
||||
_ => Err(TransportError::Process(
|
||||
"Unexpected response type".to_string(),
|
||||
pub fn check_installed(python: &mut PythonProcess, app: &str) -> Result<bool, ProcessError> {
|
||||
let request = messages::Request {
|
||||
command: Some(messages::request::Command::CheckAppInstalled(
|
||||
check::AppInstalledRequest {
|
||||
app_name: app.to_string(),
|
||||
},
|
||||
)),
|
||||
};
|
||||
|
||||
let response = python.send(request).map_err(ProcessError::Transport)?;
|
||||
|
||||
match response.result {
|
||||
Some(messages::response::Result::CheckAppInstalled(response)) => Ok(response.passed),
|
||||
Some(messages::response::Result::Error(e)) => Err(ProcessError::Health(e.message)),
|
||||
_ => Err(ProcessError::Response),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,63 +1,26 @@
|
|||
use crate::apps::Apps;
|
||||
use crate::gis::{check_gis_setup, GISError};
|
||||
use crate::templates::TemplateTags;
|
||||
use djls_ipc::{JsonResponse, PythonProcess, TransportError, TransportMessage, TransportResponse};
|
||||
use djls_ipc::v1::*;
|
||||
use djls_ipc::{ProcessError, PythonProcess, TransportError};
|
||||
use djls_python::{ImportCheck, Python};
|
||||
use serde::Deserialize;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DjangoProject {
|
||||
py: Python,
|
||||
python: PythonProcess,
|
||||
settings_module: String,
|
||||
installed_apps: Apps,
|
||||
templatetags: TemplateTags,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct DjangoSetup {
|
||||
installed_apps: Vec<String>,
|
||||
templatetags: TemplateTags,
|
||||
}
|
||||
|
||||
impl DjangoSetup {
|
||||
pub fn setup(python: &mut PythonProcess) -> Result<JsonResponse, ProjectError> {
|
||||
let message = TransportMessage::Json("django_setup".to_string());
|
||||
let response = python.send(message, None)?;
|
||||
match response {
|
||||
TransportResponse::Json(json_str) => {
|
||||
let json_response: JsonResponse = serde_json::from_str(&json_str)?;
|
||||
Ok(json_response)
|
||||
}
|
||||
_ => Err(ProjectError::Transport(TransportError::Process(
|
||||
"Unexpected response type".to_string(),
|
||||
))),
|
||||
}
|
||||
}
|
||||
version: String,
|
||||
}
|
||||
|
||||
impl DjangoProject {
|
||||
fn new(
|
||||
py: Python,
|
||||
python: PythonProcess,
|
||||
settings_module: String,
|
||||
installed_apps: Apps,
|
||||
templatetags: TemplateTags,
|
||||
) -> Self {
|
||||
fn new(py: Python, python: PythonProcess, version: String) -> Self {
|
||||
Self {
|
||||
py,
|
||||
python,
|
||||
settings_module,
|
||||
installed_apps,
|
||||
templatetags,
|
||||
version,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setup(mut python: PythonProcess) -> Result<Self, ProjectError> {
|
||||
let settings_module =
|
||||
std::env::var("DJANGO_SETTINGS_MODULE").expect("DJANGO_SETTINGS_MODULE must be set");
|
||||
|
||||
let py = Python::setup(&mut python)?;
|
||||
|
||||
let has_django = ImportCheck::check(&mut python, Some(vec!["django".to_string()]))?;
|
||||
|
@ -74,45 +37,52 @@ impl DjangoProject {
|
|||
return Ok(Self {
|
||||
py,
|
||||
python,
|
||||
settings_module,
|
||||
installed_apps: Apps::default(),
|
||||
templatetags: TemplateTags::default(),
|
||||
version: String::new(),
|
||||
});
|
||||
}
|
||||
|
||||
let response = DjangoSetup::setup(&mut python)?;
|
||||
let setup: DjangoSetup = response
|
||||
.data()
|
||||
.clone()
|
||||
.ok_or_else(|| TransportError::Process("No data in response".to_string()))
|
||||
.and_then(|data| serde_json::from_value(data).map_err(TransportError::Json))?;
|
||||
let request = messages::Request {
|
||||
command: Some(messages::request::Command::DjangoGetProjectInfo(
|
||||
django::GetProjectInfoRequest {},
|
||||
)),
|
||||
};
|
||||
|
||||
Ok(Self::new(
|
||||
let response = python
|
||||
.send(request)
|
||||
.map_err(|e| ProjectError::Transport(e))?;
|
||||
|
||||
let version = match response.result {
|
||||
Some(messages::response::Result::DjangoGetProjectInfo(response)) => {
|
||||
response.project.unwrap().version
|
||||
}
|
||||
Some(messages::response::Result::Error(e)) => {
|
||||
return Err(ProjectError::Process(ProcessError::Health(e.message)));
|
||||
}
|
||||
_ => {
|
||||
return Err(ProjectError::Process(ProcessError::Response));
|
||||
}
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
py,
|
||||
python,
|
||||
settings_module,
|
||||
Apps::from_strings(setup.installed_apps.to_vec()),
|
||||
setup.templatetags,
|
||||
))
|
||||
version,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn py(&self) -> &Python {
|
||||
&self.py
|
||||
}
|
||||
|
||||
fn settings_module(&self) -> &String {
|
||||
&self.settings_module
|
||||
fn version(&self) -> &String {
|
||||
&self.version
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for DjangoProject {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "Django Project")?;
|
||||
writeln!(f, "Settings Module: {}", self.settings_module)?;
|
||||
writeln!(f, "Installed Apps:")?;
|
||||
write!(f, "{}", self.installed_apps)?;
|
||||
writeln!(f, "Template Tags:")?;
|
||||
write!(f, "{}", self.templatetags)?;
|
||||
writeln!(f, "Version: {}", self.version)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -121,22 +91,18 @@ impl fmt::Display for DjangoProject {
|
|||
pub enum ProjectError {
|
||||
#[error("Django is not installed or cannot be imported")]
|
||||
DjangoNotFound,
|
||||
|
||||
#[error("IO error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
|
||||
#[error("GIS error: {0}")]
|
||||
Gis(#[from] GISError),
|
||||
|
||||
#[error("JSON parsing error: {0}")]
|
||||
Json(#[from] serde_json::Error),
|
||||
|
||||
#[error(transparent)]
|
||||
Packaging(#[from] djls_python::PackagingError),
|
||||
|
||||
#[error("Process error: {0}")]
|
||||
Process(#[from] ProcessError),
|
||||
#[error(transparent)]
|
||||
Python(#[from] djls_python::PythonError),
|
||||
|
||||
#[error("Transport error: {0}")]
|
||||
Transport(#[from] TransportError),
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::apps::Apps;
|
||||
use djls_ipc::{PythonProcess, TransportError};
|
||||
use djls_ipc::{ProcessError, PythonProcess, TransportError};
|
||||
use std::process::Command;
|
||||
|
||||
pub fn check_gis_setup(python: &mut PythonProcess) -> Result<bool, GISError> {
|
||||
|
@ -17,10 +17,10 @@ pub fn check_gis_setup(python: &mut PythonProcess) -> Result<bool, GISError> {
|
|||
pub enum GISError {
|
||||
#[error("IO error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
|
||||
#[error("JSON parsing error: {0}")]
|
||||
Json(#[from] serde_json::Error),
|
||||
|
||||
#[error("Process error: {0}")]
|
||||
Process(#[from] ProcessError),
|
||||
#[error("Transport error: {0}")]
|
||||
Transport(#[from] TransportError),
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue