Skip to content

Commit 643a479

Browse files
add protobuf transport and refactor to support (#24)
1 parent b3e0ee7 commit 643a479

File tree

21 files changed

+406
-74
lines changed

21 files changed

+406
-74
lines changed

.github/workflows/test.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ jobs:
3535
enable-cache: true
3636
version: ${{ env.UV_VERSION }}
3737

38+
- name: Install Protoc
39+
uses: arduino/setup-protoc@v3
40+
with:
41+
repo-token: ${{ secrets.GITHUB_TOKEN }}
42+
3843
- name: Install dependencies and build
3944
run: |
4045
uv sync --frozen

.just/proto.just

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
set unstable := true
2+
3+
justfile := justfile_directory() + "/.just/proto.just"
4+
5+
[private]
6+
default:
7+
@just --list --justfile {{ justfile }}
8+
9+
[no-cd]
10+
[private]
11+
check:
12+
#!/usr/bin/env sh
13+
if ! command -v protoc > /dev/null 2>&1; then
14+
echo "protoc is not installed. Please install protobuf-compiler"
15+
exit 1
16+
fi
17+
18+
[private]
19+
fmt:
20+
@just --fmt --justfile {{ justfile }}
21+
22+
# Generate protobuf code for both Rust and Python
23+
[no-cd]
24+
gen:
25+
@just proto rust
26+
@just proto py
27+
28+
# Generate protobuf code for Rust
29+
[no-cd]
30+
rust: check
31+
cargo build -p djls-types
32+
33+
# Generate protobuf code for Python
34+
[no-cd]
35+
py: check
36+
protoc -I=proto --python_out=python/djls proto/*.proto
37+

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ djls-django = { path = "crates/djls-django" }
99
djls-ipc = { path = "crates/djls-ipc" }
1010
djls-python = { path = "crates/djls-python" }
1111
djls-server = { path = "crates/djls-server" }
12+
djls-types = { path = "crates/djls-types" }
1213
djls-worker = { path = "crates/djls-worker" }
1314

1415
anyhow = "1.0.94"
1516
async-trait = "0.1.83"
17+
prost = "0.13"
18+
bytes = "1.9"
1619
serde = { version = "1.0.215", features = ["derive"] }
1720
serde_json = "1.0.133"
1821
thiserror = "2.0.6"

Justfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
set dotenv-load := true
22
set unstable := true
33

4+
mod proto ".just/proto.just"
5+
46
# List all available commands
57
[private]
68
default:

crates/djlc-cli/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ djls-ipc = { workspace = true }
99
djls-server = { workspace = true }
1010

1111
anyhow = { workspace = true }
12+
serde_json = { workspace = true }
1213
tokio = { workspace = true }
1314

1415
clap = { version = "4.5.23", features = ["derive"] }

crates/djlc-cli/src/main.rs

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,6 @@ impl CommonOpts {
3333
enum Commands {
3434
/// Start the LSP server
3535
Serve(CommonOpts),
36-
/// Get Python environment information
37-
Info(CommonOpts),
38-
/// Print the version
39-
Version(CommonOpts),
4036
}
4137

4238
#[tokio::main]
@@ -49,22 +45,6 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
4945
PythonProcess::new("djls.lsp", Transport::Json, opts.health_check_interval())?;
5046
djls_server::serve(python).await?
5147
}
52-
Commands::Info(opts) => {
53-
let mut python =
54-
PythonProcess::new("djls.lsp", Transport::Json, opts.health_check_interval())?;
55-
match python.send("python_setup", None) {
56-
Ok(info) => println!("{}", info),
57-
Err(e) => eprintln!("Failed to get info: {}", e),
58-
}
59-
}
60-
Commands::Version(opts) => {
61-
let mut python =
62-
PythonProcess::new("djls.lsp", Transport::Json, opts.health_check_interval())?;
63-
match python.send("version", None) {
64-
Ok(version) => println!("Python module version: {}", version),
65-
Err(e) => eprintln!("Failed to get version: {}", e),
66-
}
67-
}
6848
}
6949

7050
Ok(())

crates/djls-django/src/apps.rs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use djls_ipc::{parse_json_response, JsonResponse, PythonProcess, TransportError};
1+
use djls_ipc::{JsonResponse, PythonProcess, TransportError, TransportMessage, TransportResponse};
22
use serde::Deserialize;
33
use std::fmt;
44

@@ -55,10 +55,18 @@ impl Apps {
5555
}
5656

5757
pub fn check_installed(python: &mut PythonProcess, app: &str) -> Result<bool, TransportError> {
58-
let response = python.send("installed_apps_check", Some(vec![app.to_string()]))?;
59-
let response = parse_json_response(response)?;
60-
let result = InstalledAppsCheck::try_from(response)?;
61-
Ok(result.has_app)
58+
let message = TransportMessage::Json("installed_apps_check".to_string());
59+
let response = python.send(message, Some(vec![app.to_string()]))?;
60+
match response {
61+
TransportResponse::Json(json_str) => {
62+
let json_response: JsonResponse = serde_json::from_str(&json_str)?;
63+
let result = InstalledAppsCheck::try_from(json_response)?;
64+
Ok(result.has_app)
65+
}
66+
_ => Err(TransportError::Process(
67+
"Unexpected response type".to_string(),
68+
)),
69+
}
6270
}
6371
}
6472

crates/djls-django/src/django.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::apps::Apps;
22
use crate::gis::{check_gis_setup, GISError};
33
use crate::templates::TemplateTags;
4-
use djls_ipc::{parse_json_response, JsonResponse, PythonProcess, TransportError};
4+
use djls_ipc::{JsonResponse, PythonProcess, TransportError, TransportMessage, TransportResponse};
55
use djls_python::{ImportCheck, Python};
66
use serde::Deserialize;
77
use std::fmt;
@@ -23,9 +23,17 @@ struct DjangoSetup {
2323

2424
impl DjangoSetup {
2525
pub fn setup(python: &mut PythonProcess) -> Result<JsonResponse, ProjectError> {
26-
let response = python.send("django_setup", None)?;
27-
let response = parse_json_response(response)?;
28-
Ok(response)
26+
let message = TransportMessage::Json("django_setup".to_string());
27+
let response = python.send(message, None)?;
28+
match response {
29+
TransportResponse::Json(json_str) => {
30+
let json_response: JsonResponse = serde_json::from_str(&json_str)?;
31+
Ok(json_response)
32+
}
33+
_ => Err(ProjectError::Transport(TransportError::Process(
34+
"Unexpected response type".to_string(),
35+
))),
36+
}
2937
}
3038
}
3139

crates/djls-ipc/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ version = "0.0.0"
44
edition = "2021"
55

66
[dependencies]
7+
djls-types = { workspace = true }
8+
79
anyhow = { workspace = true }
810
async-trait = { workspace = true }
11+
prost = { workspace = true }
12+
bytes = { workspace = true }
913
serde = { workspace = true }
1014
serde_json = { workspace = true }
1115
thiserror = { workspace = true }

crates/djls-ipc/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ pub use transport::parse_raw_response;
77
pub use transport::JsonResponse;
88
pub use transport::Transport;
99
pub use transport::TransportError;
10+
pub use transport::TransportMessage;
11+
pub use transport::TransportResponse;

0 commit comments

Comments
 (0)