mermaid-server/internal/diagram.go

87 lines
2.2 KiB
Go

package internal
import (
"crypto/md5"
"encoding/base64"
"encoding/hex"
"fmt"
"strings"
"sync"
"time"
)
// NewDiagram returns a new diagram.
func NewDiagram(description []byte, imgType string) *Diagram {
// Debug: Log what we received
fmt.Printf("DEBUG: Received %d bytes\n", len(description))
fmt.Printf("DEBUG: Raw bytes: %q\n", string(description))
fmt.Printf("DEBUG: Contains newlines: %t\n", strings.Contains(string(description), "\n"))
trimmed := strings.TrimSpace(string(description))
fmt.Printf("DEBUG: After TrimSpace: %q\n", trimmed)
fmt.Printf("DEBUG: Still contains newlines: %t\n", strings.Contains(trimmed, "\n"))
return &Diagram{
description: []byte(trimmed),
lastTouched: time.Now(),
mu: &sync.RWMutex{},
imgType: imgType,
}
}
// Diagram represents a single diagram.
type Diagram struct {
// id is the ID of the Diagram
id string
// description is the description of the diagram.
description []byte
// Output is the filepath to the output file.
Output string
// mu is a mutex to protect the last touched value.
mu *sync.RWMutex
// lastTouched is the time that the diagram was last used.
lastTouched time.Time
// the type of image to generate svg or png
imgType string
}
// Touch updates the last touched time of the diagram.
func (d *Diagram) Touch() {
d.mu.Lock()
defer d.mu.Unlock()
d.lastTouched = time.Now()
}
// TouchedInDuration returns true if the diagram has been touched in the given duration.
func (d *Diagram) TouchedInDuration(duration time.Duration) bool {
d.mu.Lock()
defer d.mu.Unlock()
return time.Now().Add(-duration).Before(d.lastTouched)
}
// ID returns an ID for the diagram.
// The ID is set from the diagram description.
func (d *Diagram) ID() (string, error) {
if d.id != "" {
return d.id, nil
}
encoded := base64.StdEncoding.EncodeToString(d.description)
hash := md5.Sum([]byte(encoded))
d.id = hex.EncodeToString(hash[:]) + d.imgType
return d.id, nil
}
// Description returns the diagram description.
func (d *Diagram) Description() []byte {
return d.description
}
// Description returns the diagram description.
func (d *Diagram) WithDescription(description []byte) *Diagram {
d.description = description
d.id = ""
return d
}